前言

哈喽,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 ,自然而然的成为了最当先的分支,而且没有 mergecommit 记录,是不是感觉很难受了。

咱们在应用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库进行数据校验,开了~~~