前言
哈喽,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 readme
pick 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 readme
s 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 log
15ace34 (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 库进行数据校验,开了~~~