一、git merge 的流程
如下,首先在一个目录中初始化仓库,然后在master分支创建file01和file02两个文件,并两次提交,此时拉出dev分支,然后在master分支继续创建file03和file04,然后在dev分支创建file05和file06,每个文件分别提交,此时在dev分支中使用git merge master,把master分支的代码合入到dev分支,整个过程如下,最后可以看出使用merge合并分支,会在merge的时候,将master分支再在此期间的提交合并到当前分支的默认,然后再默认在增加一次merge的提交,在日常工作中,通常此时会继续将dev的分支merge到master分支,从而完成一次向主分支的提交,此时master分支合dev分支的提交顺序是完全一样了
[root@hecs-73797 demo]# git init
已重新初始化已存在的 Git 仓库于 /root/demo/.git/
[root@hecs-73797 demo]# touch file01
[root@hecs-73797 demo]# git add .
[root@hecs-73797 demo]# git commit -m "add file01"
[master(根提交) 1607750] add file01
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file01
[root@hecs-73797 demo]# touch file02
[root@hecs-73797 demo]# git add .
[root@hecs-73797 demo]# git commit -m "add file02"
[master 3e81d72] add file02
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file02
[root@hecs-73797 demo]# git checkout -b dev
切换到一个新分支 'dev'
[root@hecs-73797 demo]# git checkout master
切换到分支 'master'
[root@hecs-73797 demo]# touch file03
[root@hecs-73797 demo]# git add .
[root@hecs-73797 demo]# git commit -m "add file03"
[master 2aa2963] add file03
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file03
[root@hecs-73797 demo]# touch file04
[root@hecs-73797 demo]# git add .
[root@hecs-73797 demo]# git commit -m "add file04"
[master ee2dd24] add file04
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file04
[root@hecs-73797 demo]# git checkout dev
切换到分支 'dev'
[root@hecs-73797 demo]# touch file05
[root@hecs-73797 demo]# git add .
[root@hecs-73797 demo]# git commit -m "add file05"
[dev 3db4965] add file05
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file05
[root@hecs-73797 demo]# touch file06
[root@hecs-73797 demo]# git add .
[root@hecs-73797 demo]# git commit -m "add file06"
[dev cd6a2a4] add file06
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file06
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* cd6a2a4 (HEAD -> dev) add file06
* 3db4965 add file05
* 3e81d72 add file02
* 1607750 add file01
[root@hecs-73797 demo]# git merge master
Merge made by the 'ort' strategy.
file03 | 0
file04 | 0
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file03
create mode 100644 file04
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* 4fd1319 (HEAD -> dev) Merge branch 'master' into dev
|\
| * ee2dd24 (master) add file04
| * 2aa2963 add file03
* | cd6a2a4 add file06
* | 3db4965 add file05
|/
* 3e81d72 add file02
* 1607750 add file01
[root@hecs-73797 demo]# git checkout master
切换到分支 'master'
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* ee2dd24 (HEAD -> master) add file04
* 2aa2963 add file03
* 3e81d72 add file02
* 1607750 add file01
[root@hecs-73797 demo]# git merge dev
更新 ee2dd24..4fd1319
Fast-forward
file05 | 0
file06 | 0
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file05
create mode 100644 file06
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* 4fd1319 (HEAD -> master, dev) Merge branch 'master' into dev
|\
| * ee2dd24 add file04
| * 2aa2963 add file03
* | cd6a2a4 add file06
* | 3db4965 add file05
|/
* 3e81d72 add file02
* 1607750 add file01
二、git rebase的流程
可以使用git reset 先将上述回退到merge之前,比如在master分支
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* 4fd1319 (HEAD -> master, dev) Merge branch 'master' into dev
|\
| * ee2dd24 add file04
| * 2aa2963 add file03
* | cd6a2a4 add file06
* | 3db4965 add file05
|/
* 3e81d72 add file02
* 1607750 add file01
[root@hecs-73797 demo]# git reset --hard ee2dd24
HEAD 现在位于 ee2dd24 add file04
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* ee2dd24 (HEAD -> master) add file04
* 2aa2963 add file03
* 3e81d72 add file02
* 1607750 add file01
在dev分支
[root@hecs-73797 demo]# git checkout dev
切换到分支 'dev'
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* 4fd1319 (HEAD -> dev) Merge branch 'master' into dev
|\
| * ee2dd24 (master) add file04
| * 2aa2963 add file03
* | cd6a2a4 add file06
* | 3db4965 add file05
|/
* 3e81d72 add file02
* 1607750 add file01
[root@hecs-73797 demo]# git reset cd6a2a4 --hard
HEAD 现在位于 cd6a2a4 add file06
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* cd6a2a4 (HEAD -> dev) add file06
* 3db4965 add file05
* 3e81d72 add file02
* 1607750 add file01
此时在dev分支执行rebase命令,git rebase 是首先将master分支的合并进来,然后将本分支加到master分支提交记录的后面,此外可以看到此时提交记录就简洁的多了,则就是rebase和merge的主要优势
[root@hecs-73797 demo]# git rebase master
成功变基并更新 refs/heads/dev。
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* 8141efd (HEAD -> dev) add file06
* 71732f9 add file05
* ee2dd24 (master) add file04
* 2aa2963 add file03
* 3e81d72 add file02
* 1607750 add file01
此时切回到master分支需要使用merge
[root@hecs-73797 demo]# git checkout master
切换到分支 'master'
[root@hecs-73797 demo]# git merge dev
更新 ee2dd24..8141efd
Fast-forward
file05 | 0
file06 | 0
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file05
create mode 100644 file06
[root@hecs-73797 demo]# git log --graph --pretty=oneline --abbrev-commit
* 8141efd (HEAD -> master, dev) add file06
* 71732f9 add file05
* ee2dd24 add file04
* 2aa2963 add file03
* 3e81d72 add file02
* 1607750 add file01
三、git rebase 和 git merge区别总结
1、git meerge 是将当前分支的提交放在merge分支的前面,而git rebase是将当前分支的提交放到reabse分支的后面
2、git merge 会在最后增加一个merge的提交记录,而git rebase 不会额外增加提交记录
3、git merge 合并之后提交记录是非常复杂的,而使用git rebase合并之后提交记录是线性的
4、使用git merge 合并之后就不能再回退自己的提交代码了,如果回退则会降merge的内容一同回退了,而git rebase在合并之后可以继续回退自己的提交,而从rebase合进来的代码不受影响
5、很明显,dev开发分支适合使用git rebase,而master主分支则非常适合git merge
6、master主分支如果使用git rebase的后果是改变了提交历史,比如多人合作时后使用rebase的必须将前面使用过rebase的代码合到自己的前面,导致跟拉出来分支的时候提交历史不一样了,从而会带来各种比较痛苦的提交体验