从git log 点线图(graph)看merge和rebase操作
why?
为什么要写一篇这样的文章?
- 团队开发中是选择rebase还是merge?
- rebase/merge两者之间究竟有何不同?
- git log的点线图如何理解?
- git log 常见的命令选择?
- 如何从Gitlog中查找凶手?
以上就是本文需要简单介绍的内容。
我会从一个最简单的示例开始演进团队开发的全部过程,虽不尽详细但是可以窥见一个大致的过程。
本地操作记录
创建Git和master并且初次提交(master-first-commit)
➜ GitGraph git:(branch01) /Users/zhuge/Desktop/GitGraph
➜ GitGraph git init
Initialized empty Git repository in /Users/zhuge/Desktop/GitGraph/.git/
➜ GitGraph git:(master) touch master
➜ GitGraph git:(master) ✗ git add .
➜ GitGraph git:(master) ✗ gcam 'master-first-commit'
[master (root-commit) facfb68] master-first-commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master
创建br1和br2, 并且br1初次提交(br1-first-commit)
➜ GitGraph git:(master) gb br1
➜ GitGraph git:(master) gb br2
➜ GitGraph git:(master) gco br1
Switched to branch 'br1'
➜ GitGraph git:(br1) touch br1
➜ GitGraph git:(br1) ✗ git add .
➜ GitGraph git:(br1) ✗ gcam 'br1-first-commit'
[br1 00b2a4c] br1-first-commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 br1
master前进,第2次提交(master-second-commit)
➜ GitGraph git:(br1) gco master
Switched to branch 'master'
➜ GitGraph git:(master) touch master2
➜ GitGraph git:(master) ✗ git add .
➜ GitGraph git:(master) ✗ gcam 'master-second-commit'
[master d5c36b0] master-second-commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master2
br2初次提交(br2-first-commit)
➜ GitGraph git:(master) gco br2
Switched to branch 'br2'
➜ GitGraph git:(br2) touch br2
➜ GitGraph git:(br2) ✗ git add .
➜ GitGraph git:(br2) ✗ gcam 'br2-first-commit'
[br2 b3ebbd7] br2-first-commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 br2
➜ GitGraph git:(br2)
br1 merge master
➜ GitGraph git:(br2) gco br1
Switched to branch 'br1'
➜ GitGraph git:(br1) git merge master
Merge made by the 'recursive' strategy.
master2 | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master2
br2 rebase master
➜ GitGraph git:(br2) gco master
Switched to branch 'master'
➜ GitGraph git:(master) touch m3
➜ GitGraph git:(master) ✗ git add .
➜ GitGraph git:(master) ✗ gcam 'master-third-commit'
[master 763f88e] master-third-commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 m3
➜ GitGraph git:(master) gco br2
Switched to branch 'br2'
➜ GitGraph git:(br2) git rebase master
First, rewinding head to replay your work on top of it...
Applying: br2-first-commit
➜ GitGraph git:(br2)
git 开发简单流程
- 主干master稳定
- 切出feature分支br1, br2
- br1,br2独立前进:commit
- master合稳定功能,前进: master-second-commit
- br1合入master代码:rebase方式
- br2合入master代码:merge
- br1,br2前进:commit
- br1, br2稳定准备合入master
- master merge br1/br2
- 功能完毕,回到第2步骤循环往复,不断迭代bug
git log常见命令
演示中操作在zsh (Oh My Zsh is a delightful, open source, community-driven framework for managing your Zsh configuration. https://ohmyz.sh/) 中进行,为了方便查看并没有使用git flow。
- glol
- git log –graph –decorate –oneline –simplify-by-decoration –all
- git log –graph
br2 git log点线图
为什么先看br2呢?因为rebase相比于merge使用更少一些尤其在小团队开发中。先来看这个陌生人吧!
- glol
➜ GitGraph git:(br2) glol
- 只看commit前部可以看见只有4个*,并且没有合入迹象。
- 看具体信息:首先时间上即使master-third-commit操作在br2-first-commit前,但是rebase之后时间也是在其之后。
- 因为rebase本身操作就是将切入点后的所有提交全部取出,将master后面的commit全部patch到master上,这一步是不会产生冲突的。这之后会将取出的commits重新按照顺序patch上去,此时可能会产生冲突。
- 基于此最终的log就是按照顺序的一个综合结果
看log info可以发现master的提交都是顺序的, 此时head指向了br2
* 62765a6 - (HEAD -> br2) br2-first-commit (43 seconds ago) <zhuge>
* 763f88e - (master) master-third-commit (52 seconds ago) <zhuge>
* d5c36b0 - master-second-commit (11 minutes ago) <zhuge>
* facfb68 - master-first-commit (12 minutes ago) <zhuge>
- git log –graph
相对比glol显示了更多的信息。
➜ GitGraph git:(br2) git log --graph
* commit 62765a62d67b0fb3955ff30e86cdf255b1c751c3 (HEAD -> br2)
| Author: zhuge <zhuge@bilibili.com>
| Date: Fri Sep 7 11:27:38 2018 +0800
|
| br2-first-commit
|
* commit 763f88e6737a1dad5498cd8601077068590282f1 (master)
| Author: zhuge <zhuge@bilibili.com>
| Date: Fri Sep 7 11:36:48 2018 +0800
|
| master-third-commit
|
* commit d5c36b01b8f701b89ba3ab0619f2d13d659268e2
| Author: zhuge <zhuge@bilibili.com>
| Date: Fri Sep 7 11:26:40 2018 +0800
|
| master-second-commit
|
* commit facfb683c432f7497be0faf73f570342c7eea1c6
Author: zhuge <zhuge@bilibili.com>
Date: Fri Sep 7 11:25:14 2018 +0800
master-first-commit
- git log –graph –decorate –oneline –simplify-by-decoration –all
➜ GitGraph git:(br2) git log --graph --decorate --oneline --simplify-by-decoration --all
参数解释:
--decorate: 标记会让git log显示每个commit的引用
--oneline: 一行显示
--simplify-by-decoration:只显示被branch或tag引用的commit
--all: 所有分支
全参数
* 62765a6 (HEAD -> br2) br2-first-commit
* 763f88e (master) master-third-commit
| * e320d7c (br1) Merge branch 'master' into br1
|/
* facfb68 master-first-commit
(END)
你也可以尝试调整参数的增减,目前我个人最喜欢的选择如下:
➜ GitGraph git:(br2) git log --graph --decorate --oneline --all
如上图所示:
符号解释:
*表示一个commit, 注意不要管*在哪一条主线上
|表示分支前进
/表示分叉
\表示合入
过程解释:
1. base master: master first commit
2. |/这个符号表示新分支, 可以看见是新增br1: br1-first-commit
3. master前进:master-second-commit
4. master merged into br1
5. master前进:master-third-commit
6. br2前进:br2-first-commit(rebase)
7. br2前进:br2-second-commit(rebase【此commit在rebase后提交】)
br1 git log点线图
glol
➜ GitGraph git:(br1) glol
git log –graph
➜ GitGraph git:(br1) git log --graph
可以看见master first commit的base上,叉出分支br1,br1前进first commit,然后master 前进, 最后有一个merge标记并且当前HEAD在br1
rebase vs merge
以下都是个人理解,如有问题请在评论区说明。
1. rebase也叫变基,是指feature功能分支在从主干分支切出来之后,主干和功能分支独立前进几个提交之后。功能分支需要合入最新的主干代码而进行的操作。对br2的rebase操作相当于以下操作:
最新的master
gb br3: 创建分支br3
gco br3: 切入br3
br3 cherry-pick br2-first-commit: br3 cp了br2后面的commit
br3 change name to br2, delete br2
- merge操作就没有rebase那么优雅干净了,直接将代码的修改插入。commit log的顺序按照提交先后。
- rebase的优势:如果你在一个分支上的提交有20个,而主干因为团队提交了30个commit,此时主干rebase进来的30个commit肯定排在前面。这样比较符合逻辑,因为虽然按照commit的时间,你有部分代码可能会在30个commit中间,但是并不是稳定的代码就是一堆bug,算不上产出。如果是以稳定为优先级,rebase肯定是最佳的。另外 rebase 的话你所有的提交都会在一起,查找起来会非常方便. git log点线图是一条线看起来非常舒服。
- rebase的问题:的确会失去一些关于时间上面的信息,例如分支切出的点信息会丢失。
- merge的优势:就是保证了时间信息的准确性
- merge的问题:引入了一次不必要的history join,git log点线图会非常难看,增加了查看log的成本。
基于以上个人会选择rebase方式如何代码。
另外介绍rebase的另一个操作
git rebase -i commitID
这个命令可以合并几个commit,如果你的commit修改会出现比较零散内容的时候,例如修改bug,合并提交会让log看起来很干净。
master merge feature
➜ GitGraph git:(br1) gco master
Switched to branch 'master'
➜ GitGraph git:(master) git merge br2
Updating 763f88e..0f4e670
上图可以看见br2合入之后log依然很是清晰。
加入br1的信息之后log就不那么漂亮了,不漂亮就会给找凶手带来难度,尤其是在commit的人和次数变多的时候。
➜ GitGraph git:(master) git merge br1
Merge made by the 'recursive' strategy.
上图可以看见merge的br1于master的*线不在一起,有很多分叉信息需要你费尽的查阅。如果你觉得好像还可以的话,请看下面的图:
更多推荐
所有评论(0)