前言
哈喽,everybody,人不知;鬼不觉8天的小长假也靠近了序幕,游玩了这么多天,明天也要收一收心,开始学习了呦~。今天就要下班啦,明天姐姐忽然问我git-rebase指令是干什么的,怎么用?其实我是不想给他讲的,然而还是没有逃过姐姐的软磨硬泡,那么咱们就一起来看一看什么是git-rebase吧!!!
缘起
话说,我和姐姐的缘分是在那一个月黑风高的早晨,啪,姐姐一巴掌打在了我的脸上并说了一句:能不能讲重点~~~。哈哈,不开玩笑了,间接说重点吧。咱们先来看一个场景,我查看了一下我github上的集体仓库,commit
提交次数很多,提交内容如下:
这么多的提交,有很多没有标准的命名,因为是本人应用,就轻易开整了,这的确不好,还有一些没有必要的提交,其实是能够合并到一起的,这样会导致如下问题:
- 造成分支净化,我的项目中充斥了许多
commit
记录,当呈现紧急问题须要回滚代码时,就只能一条条的查看了。 - 代码
review
不不便,当你要做code review
时,一个很小的性能却提交了很屡次,看起来就不是很不便了。
这一篇文章咱们先不讲git
提交标准,咱们先来解决一下如何合并屡次提交记录。
rebase作用一:合并提交记录
通过下面的场景,咱们能够引申出git-rebase
的第一个作用:合并提交记录。当初咱们想合并最近5次的提交记录,执行:
$ git rebase -i HEAD~2
执行该指令后会自动弹出vim
编辑模式:
pick e2c71c6 update readmepick 3d2c660 wip: merge`# Rebase 5f47a82..3d2c660 onto 5f47a82 (2 commands)## Commands:# p, pick <commit> = use commit# r, reword <commit> = use commit, but edit the commit message# e, edit <commit> = use commit, but stop for amending# s, squash <commit> = use commit, but meld into previous commit# f, fixup <commit> = like "squash", but discard this commit's log message# x, exec <command> = run command (the rest of the line) using shell# b, break = stop here (continue rebase later with 'git rebase --continue')# d, drop <commit> = remove commit# l, label <label> = label current HEAD with a name# t, reset <label> = reset HEAD to a label# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]# . create a merge commit using the original merge commit's# . message (or the oneline, if no original merge commit was# . specified). Use -c <commit> to reword the commit message.## These lines can be re-ordered; they are executed from top to bottom.## If you remove a line here THAT COMMIT WILL BE LOST.## However, if you remove everything, the rebase will be aborted.## Note that empty commits are commented out
从这里咱们能够看出后面5行是咱们要合并的记录,不过后面都带了一个雷同的指令:pick
,这是什么指令呢,不要慌,这不,上面曾经给出了commands
:
pick:保留该commit(缩写:p)reword:保留该commit,但我须要批改该commit的正文(缩写:r)edit:保留该commit, 但我要停下来批改该提交(不仅仅批改正文)(缩写:e)squash:将该commit和前一个commit合并(缩写:s)fixup:将该commit和前一个commit合并,但我不要保留该提交的正文信息(缩写:f)exec:执行shell命令(缩写:x)drop:我要抛弃该commit(缩写:d)label:用名称标记以后HEAD(缩写:l)reset:将HEAD重置为标签(缩写:t)merge:创立一个合并分支并应用原版分支的commit的正文(缩写:m)
依据这些指令,咱们能够进行批改,如下:
pick e2c71c6 update readmes 3d2c660 wip: merge`
批改好后,咱们点击保留退出,就会进入正文界面:
# This is a combination of 2 commits.# This is the 1st commit message:update readme# This is the commit message #2:wip: merge`# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Date: Thu Sep 17 22:03:52 2020 +0800## interactive rebase in progress; onto 5f47a82# Last commands done (2 commands done):# pick e2c71c6 update readme# squash 3d2c660 wip: merge`# No commands remaining.# You are currently rebasing branch 'master' on '5f47a82'.## Changes to be committed:# new file: hash/.idea/.gitignore# new file: hash/.idea/hash.iml# new file: hash/.idea/misc.xml# new file: hash/.idea/modules.xml# new file: hash/.idea/vcs.xml# new file: hash/go.mod# new file: hash/hash/main.go# modified: snowFlake/Readme.md
下面把每一次的提交的meassage
都列出了,因为咱们要合并这两次的commit
,所以提交正文能够批改成一条,最终编辑如下:
# This is a combination of 2 commits.# This is the 1st commit message:fix: merge update and wip: merge`# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Date: Thu Sep 17 22:03:52 2020 +0800## interactive rebase in progress; onto 5f47a82# Last commands done (2 commands done):# pick e2c71c6 update readme# squash 3d2c660 wip: merge`# No commands remaining.# You are currently rebasing branch 'master' on '5f47a82'.## Changes to be committed:# new file: hash/.idea/.gitignore# new file: hash/.idea/hash.iml# new file: hash/.idea/misc.xml# new file: hash/.idea/modules.xml# new file: hash/.idea/vcs.xml# new file: hash/go.mod# new file: hash/hash/main.go# modified: snowFlake/Readme.md
编辑好后,保留退出就能够了。这样就实现了一次合并commit
。咱们来验证一下:
$ git log15ace34 (HEAD -> master) fix: merge update and wip: merge`5f47a82 update snowFlake code
从这里咱们能够看到,两次提交变成了一次,缩小了无用的提交信息。
作用二:分支合并
这个作用咱们应用的很少,然而还是要晓得,上面咱们一起来看一下应用场景。
假如咱们当初有一个新我的项目,当初咱们要从master
分支切出来一个dev
分支,进行开发:
$ git checkout -b dev
这时候,你的共事实现了一次 hotfix
,并合并入了 master
分支,此时 master
曾经当先于你的 dev
分支了:
共事修复完预先,在群里告诉了一声,正好是你须要的局部,所以咱们当初要同步master
分支的改变,应用merge
进行合并:
$ git merge master
图中绿色的点就是咱们合并之后的后果,执行git log
就会在记录里发现一些 merge
的信息,然而咱们感觉这样净化了 commit
记录,想要放弃一份洁净的 commit
,怎么办呢?这时候,git rebase
就派上用场了。
所以当初咱们来试一试应用git rebase
,咱们先回退到共事 hotfix
后合并 master
的步骤,我当初不应用merge
进行合并了,间接应用rebase
指令
$ git rebase master
这时,git
会把dev
分支外面的每个commit
勾销掉,而后把下面的操作长期保留成 patch
文件,存在 .git/rebase
目录下;而后,把 dev
分支更新到最新的 master
分支;最初,把下面保留的 patch
文件利用到 dev
分支上;
从 commit
记录咱们能够看进去,dev
分支是基于 hotfix
合并后的 master
,自然而然的成为了最当先的分支,而且没有 merge
的 commit
记录,是不是感觉很难受了。
咱们在应用rebase
合并分支时,也会呈现conflict
,在这种状况下,git
会进行 rebase
并会让你去解决抵触。在解决完抵触后,用 git add
命令去更新这些内容。而后再次执行git rebase --continue
,这样git
会持续利用余下的 patch
补丁文件。
如果咱们当初不想在执行这次rebase
操作了,都能够通过--abort
回到开始前状态:
git rebase --abort
rebase
是存在危险的操作 - 慎用
咱们当初应用rebase
操作看起来是完满的,然而他也是存在肯定危险的,上面咱们就一起来看一看。
当初假如咱们在dev
分支进行开发,执行了rebase
操作后,在提交代码到近程之前,是这样的:
提交dev
分支到近程代码仓库后,就变成了这样:
而此时你的共事也在 dev
上开发,他的分支仍然还是以前的dev
,并没有进行同步master
:
那么当他 pull
近程 master
的时候,就会有失落提交纪录。这就是为什么咱们常常听到有人说 git rebase
是一个危险命令,因为它扭转了历史,咱们应该审慎应用。
不过,如果你的分支上须要 rebase
的所有 commits
历史还没有被 push
过,就能够平安地应用 git-rebase
来操作。
总结
在asong
的仔细解说下,姐姐齐全搞懂了怎么应用git rebase
,咱们来看一下姐姐的总结:
- 当咱们在一个过期的分支下面开发的时候,执行
rebase
以此同步master
分支最新变动; - 如果咱们要启动一个搁置了很久的并行工作,当初有工夫来持续这件事件,很显然这个分支曾经落后了。这时候须要在最新的基准下面开始工作,所以
rebase
是最合适的抉择。 git-rebase
很完满,解决了咱们的两个问题:- 合并
commit
记录,放弃分支整洁; - 相比
merge
来说会缩小分支合并的记录;
- 合并
- 应用
rebase
操作要留神一个问题,如果你的分支上须要rebase
的所有commits
历史还没有被push
过,就能够平安地应用git-rebase
来操作。
看来姐姐是真的学会了,那你们呢?
没有学会不要紧,亲自试验一下能力更好的了解呦~~~。
好啦这一篇文章到这里就完结了,咱们下期见。
结尾给大家发一个小福利吧,最近我在看[微服务架构设计模式]这一本书,讲的很好,本人也收集了一本PDF,有须要的小伙能够到自行下载。获取形式:关注公众号:[Golang梦工厂],后盾回复:[微服务],即可获取。
我翻译了一份GIN中文文档,会定期进行保护,有须要的小伙伴后盾回复[gin]即可下载。
我是asong,一名普普通通的程序猿,让我一起缓缓变强吧。我本人建了一个golang
交换群,有须要的小伙伴加我vx
,我拉你入群。欢送各位的关注,咱们下期见~~~
举荐往期文章:
- 手把手教姐姐写音讯队列
- 详解Context包,看这一篇就够了!!!
- go-ElasticSearch入门看这一篇就够了(一)
- 面试官:go中for-range应用过吗?这几个问题你能解释一下起因吗
- 学会wire依赖注入、cron定时工作其实就这么简略!
- 据说你还不会jwt和swagger-饭我都不吃了带着实际我的项目我就来了
- 把握这些Go语言个性,你的程度将进步N个品位(二)
- go实现多人聊天室,在这里你想聊什么都能够的啦!!!
- grpc实际-学会grpc就是这么简略
- go规范库rpc实际
- 2020最新Gin框架中文文档 asong又捡起来了英语,用心翻译
- 基于gin的几种热加载形式
- boss: 这小子还不会应用validator库进行数据校验,开了~~~