版本管理之gitlab实践教程:基础篇(13)

rebase VS merge

git中使用rebase或者merge都能达到合并的效果,什么时候更适合使用rebase,什么时候应该使用merge,在这篇文章中会通过一些简单的操作来进行讨论。

准备

使用官方介绍使用的典型场景,具体如下所示:
这里写图片描述

git准备

使用git进行事前的准备,在master(origin分支)上创建C1和C2文件然后提交,接下来创建mywork分支,在mywork分支上如法炮制添加C5和C6,同时在master分支上添加C3和C4,具体准备用的脚本如下:

liumiaocn:tmp liumiao$ cat prepare.sh 
#!/bin/sh

cd /tmp
mkdir gittest
cd gittest
ls
git init
touch C1; git add C1; git commit -m"add C1";
touch C2; git add C2; git commit -m"add C2";
git checkout -b mywork master
ls
touch C5; git add C5; git commit -m"add C5";
touch C6; git add C6; git commit -m"add C6";
git checkout master
ls
touch C3; git add C3; git commit -m"add C3";
touch C4; git add C4; git commit -m"add C4";
cd ..
cp -pR gittest gittestrebase
cp -pR gittest gittestmerge
liumiaocn:tmp liumiao$

执行准备脚本

liumiaocn:tmp liumiao$ sh prepare.sh 
Initialized empty Git repository in /private/tmp/gittest/.git/
[master (root-commit) 8ce6a5c] add C1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C1
[master 630194a] add C2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C2
Switched to a new branch 'mywork'
C1 C2
[mywork 8ad4faf] add C5
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
[mywork 45e9727] add C6
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C6
Switched to branch 'master'
C1 C2
[master ffe4260] add C3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C3
[master e931c8d] add C4
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C4
liumiaocn:tmp liumiao$

准备结果确认

liumiaocn:tmp liumiao$ cd /tmp/gittestrebase/
liumiaocn:gittestrebase liumiao$ git log --pretty=oneline
e931c8d0d050df31ce65bb8c85ed99b5a860cd38 (HEAD -> master) add C4
ffe42607e31b6c693c3bc86b32c4fb9c6c07afc6 add C3
630194ab4f0b3e46ae5fff0914d048ae72ef99b3 add C2
8ce6a5ccd864fb7cf70dbbe877b3910cdf92516e add C1
liumiaocn:gittestrebase liumiao$ 
liumiaocn:gittestrebase liumiao$ cd ../gittestmerge/
liumiaocn:gittestmerge liumiao$ git log --pretty=oneline
e931c8d0d050df31ce65bb8c85ed99b5a860cd38 (HEAD -> master) add C4
ffe42607e31b6c693c3bc86b32c4fb9c6c07afc6 add C3
630194ab4f0b3e46ae5fff0914d048ae72ef99b3 add C2
8ce6a5ccd864fb7cf70dbbe877b3910cdf92516e add C1
liumiaocn:gittestmerge liumiao$ 

merge操作

在master分支上,使用git merge mywork即可将mywork分支的内容合并过来:

liumiaocn:gittestmerge liumiao$ git branch
* master
  mywork
liumiaocn:gittestmerge liumiao$ git merge --no-ff mywork
Merge made by the 'recursive' strategy.
 C5 | 0
 C6 | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 C5
 create mode 100644 C6
liumiaocn:gittestmerge liumiao$ 
liumiaocn:gittestmerge liumiao$ git log --pretty=oneline
2d5ceb9dcafca7003fd079b571b78369e5ba4aba (HEAD -> master) Merge branch 'mywork'
e931c8d0d050df31ce65bb8c85ed99b5a860cd38 add C4
45e9727b8e5c534887affd5820ee32b7d4d02072 (mywork) add C6
ffe42607e31b6c693c3bc86b32c4fb9c6c07afc6 add C3
8ad4faf156bcbe17519edadfdbec5f41461ec93a add C5
630194ab4f0b3e46ae5fff0914d048ae72ef99b3 add C2
8ce6a5ccd864fb7cf70dbbe877b3910cdf92516e add C1
liumiaocn:gittestmerge liumiao$

rebase操作

如果使用rebase操作, 也可以类似的进行合并:

liumiaocn:gittestmerge liumiao$ cd ../gittestrebase/
liumiaocn:gittestrebase liumiao$ git branch
* master
  mywork
liumiaocn:gittestrebase liumiao$ git rebase mywork
First, rewinding head to replay your work on top of it...
Applying: add C3
Applying: add C4
liumiaocn:gittestrebase liumiao$ 
liumiaocn:gittestrebase liumiao$ git log --pretty=oneline
84dc3e7b8a20e066fcc684f4f6bb687f0e493e0a (HEAD -> master) add C4
a3db9575b2a322ec6b46d72a4b946164f961bf6e add C3
45e9727b8e5c534887affd5820ee32b7d4d02072 (mywork) add C6
8ad4faf156bcbe17519edadfdbec5f41461ec93a add C5
630194ab4f0b3e46ae5fff0914d048ae72ef99b3 add C2
8ce6a5ccd864fb7cf70dbbe877b3910cdf92516e add C1
liumiaocn:gittestrebase liumiao$

主要区别

虽然都可以实现最基本的类似合并的操作,但是两条命令使用的场景还是有所不同的,merge就是用于分支合并,而rebase并不是为了同样功能不同的实现,而是重点放在了“RE(重新做)Base“这个点上了,如何重新做,类似redo,将每一个commit重新执行一遍,在这个过程中自然后很多事情可以做,结合cherry pick可以进行有选择的提交或者本地部分提交,这个适用于多个功能并行开发但是实际上线的时间参差不齐管理复杂的情况,多多少少rebase还是能提供一种一定程度的解决方法的。
另外rebase的操作跟merge的fast foward的方式一样都是一条线的方式,而merge是使用no-ff则可将分支的信息很好的保存和记录下来,在同一个feature或者bug修正进行了多次提交的时候,使用no-ff可以更好地了解多次提交和具体feature或者bug修正的对应关系。另外,使用git log –graph也能看出这两者的一些区别:

liumiaocn:gittestrebase liumiao$ git log --graph --pretty=oneline
* 84dc3e7b8a20e066fcc684f4f6bb687f0e493e0a (HEAD -> master) add C4
* a3db9575b2a322ec6b46d72a4b946164f961bf6e add C3
* 45e9727b8e5c534887affd5820ee32b7d4d02072 (mywork) add C6
* 8ad4faf156bcbe17519edadfdbec5f41461ec93a add C5
* 630194ab4f0b3e46ae5fff0914d048ae72ef99b3 add C2
* 8ce6a5ccd864fb7cf70dbbe877b3910cdf92516e add C1
liumiaocn:gittestrebase liumiao$ 
liumiaocn:gittestrebase liumiao$ cd ../gittestmerge/
liumiaocn:gittestmerge liumiao$ git log --graph --pretty=oneline
*   2d5ceb9dcafca7003fd079b571b78369e5ba4aba (HEAD -> master) Merge branch 'mywork'
|\  
| * 45e9727b8e5c534887affd5820ee32b7d4d02072 (mywork) add C6
| * 8ad4faf156bcbe17519edadfdbec5f41461ec93a add C5
* | e931c8d0d050df31ce65bb8c85ed99b5a860cd38 add C4
* | ffe42607e31b6c693c3bc86b32c4fb9c6c07afc6 add C3
|/  
* 630194ab4f0b3e46ae5fff0914d048ae72ef99b3 add C2
* 8ce6a5ccd864fb7cf70dbbe877b3910cdf92516e add C1
liumiaocn:gittestmerge liumiao$

猜你喜欢

转载自blog.csdn.net/liumiaocn/article/details/79255078