git rebase 让你的提交记载愈加明晰可读
git rebase 的运用
rebase 翻译为变基,它的效果和 merge 很相似,用于把一个分支的修正兼并到别的一个分支上。
如下图所示,下图介绍了经过 rebase 前后提交前史的改变状况。
现在咱们来用一个比如来解释一下上面的进程。
假定咱们现在有2条分支,一个为 master\color{#2196F3}{master} ,一个为 feature/1\color{#2196F3}{feature/1},他们都根据初始的一个提交 addreadme\color{#2196F3}{add \ readme} 进行检出分支,之后,master 分支增加了 3.js\color{red}{3.js},和 4.js\color{red}{4.js} 的文件,分别进行了2次提交,feature/1\color{#2196F3}{feature/1} 也增加了 1.js\color{red}{1.js} 和 2.js\color{red}{2.js} 的文件,分别对应以下2条提交记载。
master\color{#2196F3}{master} 分支如下图:
feature/1\color{#2196F3}{feature/1} 分支如下图:
结合起来看是这样的:
此刻,切换到feature/1 分支下,履行git rebase master
,成功之后,经过 log 检查记载。
如下图所示:可以看到先是逐个应用了 master 分支的更改,然后以master\color{#2196F3}{master} 分支最终的提交作为基点,再逐个应用feature/1\color{#2196F3}{feature/1} 的每个更改。
所以,咱们的提交记载就会非常明晰,没有分叉,上面演示的是比较顺利的状况,但是大部分状况下,rebase 的进程中会产生抵触的,此刻,就需求手动处理抵触,然后运用 git add
、git rebase --continue
的方式来处理抵触,完结 rebase
,假如不想要某次 rebase
的结果,那么需求运用 git rebase --skip
来越过这次 rebase
。
git merge 和 git rebase 的区别
不同于git rebase
的是,git merge
在不是fast-forward
(快速兼并)的状况下,会产生一条额外的兼并记载,相似 Merge branch 'xxx' into 'xxx'
的一条提交信息。
别的,在处理抵触的时分,用merge
只需求处理一次抵触即可,简略粗暴,而用rebase
的时分 ,需求一次又一次的处理抵触。
git rebase 交互模式
在开发中,常会遇到在一个分支上产生了许多的无效的提交,这种状况下运用rebase
的交互式模式可以把现已发生的多次提交压缩成一次提交,得到了一个干净的提交前史,例如某个分支的提交前史状况如下:
进入交互式模式的方法是履行:
git rebase -i <base-commit>
参数 base-commit
就是指明操作的基点提交目标,根据这个基点进行 rebase
的操作,关于上述提交前史的比如,咱们要把最终的一个提交目标 (ac18084\color{#F19E38}{ac18084}) 之前的提交压缩成一次提交,咱们需求履行的指令格局是
git rebase -i ac18084
此刻会进入一个vim
的交互式页面,修正器列出的信息像下列这样。
想要兼并这一堆更改,咱们要运用squash
策略进行兼并,即把当时的commit
和它的上一个commit
内容进行兼并, 大概可以表明为下面这样。
pick ... ...
s ... ...
s ... ...
s ... ...
修正文件后 按下 :
然后 wq
保存退出,此刻又会弹出一个修正页面,这个页面是用来修正提交的信息,修正为 feat:
更正,最终保存一下,接着运用 git branch
检查提交的 commit
信息,rebase
后的提交记载如下图所示,是不是清新了许多? rebase
操作可以让咱们的提交前史变得愈加明晰。
特别注意,只能在自己运用的 feature 分支上进行 rebase 操作,不允许在集成分支上进行 rebase,由于这种操作会修正集成分支的前史记载。
rebase 的危险
patch:【假定本地分支为 dev1,c1 和 c2 是本地往 dev1 分支上做的两次提交】把 dev1 分支上的c1和 c2 “拆”下来,并临时保存成 c1′ 和 c2’。git 里将其称为 patch
rebase\color{red}{rebase} 会将当时分支的新提交拆下来,保存成 patch\color{red}{patch},然后兼并进其他分支新的 commit\color{red}{commit},最终将 patch\color{red}{patch} 接进当时分支。这是 rebase\color{red}{rebase} 对多条分支的操作。关于单条分支,rebase\color{red}{rebase} 还可以兼并多个 commit\color{red}{commit} 单号,将多个提交兼并成一个提交。
git rebase -i [commit id]
指令可以兼并(整改) commit id
之前的一切 commit\color{red}{commit} 单。加上-i
选项可以提供一个交互界面,分阶段修正commit信息并 rebase\color{red}{rebase}。
但这儿就会呈现一个问题:假如你兼并多个单号时,一不小心兼并多了,将别人的提交也兼并了,此刻你本地的 commithistory\color{red}{commit \ history} 和长途库房的 commithistory\color{red}{commit \ history} 不一样了,不管你如何 push\color{red}{push},都无法推送你的代码了。假如你并不记住 rebase\color{red}{rebase} 之前的 HEAD\color{red}{HEAD} 指向的 commit\color{red}{commit} 的 commitID\color{red}{commit \ ID} 的话,gitreflog\color{red}{git \ reflog} 都救不了你。
tips: 你可以 push\color{red}{push} 时带上 −f\color{red}{-f} 参数,强制掩盖长途 commithistory\color{red}{commit \ history},你这样做估计会被打,由于掩盖之后,团队的其他人的本地 commithistory\color{red}{commit \ history} 就与长途的不一样了,都无法推送了。
因而,请确保仅仅对自己私有的提交单进行 rebase\color{red}{rebase} 操作,关于现已兼并进长途库房的前史提交单,不要运用 rebase\color{red}{rebase} 操作兼并 commit\color{red}{commit} 单。