这一次彻底搞懂 Git Rebase
source link: http://jartto.wang/2018/12/11/git-rebase/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
使用 Git 已经好几年了,却始终只是熟悉一些常用的操作。对于 Git Rebase 却很少用到,直到这一次,不得不用。
一、起因
上线构建的过程中扫了一眼代码变更,突然发现, commit
提交竟然多达 62
次。我们来看看都提交了什么东西:
这里我们先不说 git
提交规范,就单纯这么多次无用的 commit
就很让人不舒服。可能很多人觉得无所谓,无非是多了一些提交纪录。
然而,并非如此,你可能听过破窗效应,编程也是如此!
二、导致问题
1.不利于代码 review
设想一下,你要做 code review
,结果一个很小的功能,提交了 60
多次,会不会有一些崩溃?
2.会造成分支污染
你的项目充满了无用的 commit
纪录,如果有一天线上出现了紧急问题,你需要回滚代码,却发现海量的 commit
需要一条条来看。
遵循项目规范才能提高团队协作效率,而不是随心所欲。
三、如何合并多次提交纪录?
基于上面所说问题,我们不难想到:每一次功能开发, 对多个 commit 进行合并处理。
这时候就需要用到 git rebase
了。这个命令没有太难,不常用可能源于不熟悉,所以我们来通过示例学习一下。
1.我们来合并最近的 4 次提交纪录,执行:
git rebase -i HEAD~4
2.这时候,会自动进入 vi
编辑模式:
s cacc52da add: qrcode s f072ef48 update: indexeddb hack s 4e84901a feat: add indexedDB floder s 8f33126c feat: add test2.js # Rebase 5f2452b2..8f33126c onto 5f2452b2 (4 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # 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. #
有几个命令需要注意一下:
- p, pick = use commit
- r, reword = use commit, but edit the commit message
- e, edit = use commit, but stop for amending
- s, squash = use commit, but meld into previous commit
- f, fixup = like “squash”, but discard this commit’s log message
- x, exec = run command (the rest of the line) using shell
- d, drop = remove commit
按照如上命令来修改你的提交纪录:
s cacc52da add: qrcode s f072ef48 update: indexeddb hack s 4e84901a feat: add indexedDB floder p 8f33126c feat: add test2.js
3.如果保存的时候,你碰到了这个错误:
error: cannot 'squash' without a previous commit
注意不要合并先前提交的东西,也就是已经提交远程分支的纪录。
4.如果你异常退出了 vi
窗口,不要紧张:
git rebase --edit-todo
这时候会一直处在这个编辑的模式里,我们可以回去继续编辑,修改完保存一下:
git rebase --continue
5.查看结果
git log
三次提交合并成了一次,减少了无用的提交信息。
四、Rebase 的另外一种使用场景:分支合并
1.我们先从 master
分支切出一个 dev
分支,进行开发:
git:(master) git checkout -b feature1
2.这时候,你的同事完成了一次 hotfix
,并合并入了 master
分支,此时 master
已经领先于你的 feature1
分支了:
3.恰巧,我们想要同步 master
分支的改动,首先想到了 merge
,执行:
git:(feature1) git merge master
图中绿色的点就是我们合并之后的结果,执行:
git:(feature1) git log
就会在记录里发现一些 merge
的信息,但是我们觉得这样污染了 commit
记录,想要保持一份干净的 commit
,怎么办呢?这时候, git rebase
就派上用场了。
4.让我们来试试 git rebase
,先回退到同事 hotfix
后合并 master
的步骤:
5.使用 rebase
后来看看结果:
git:(feature1) git rebase master
这里补充一点: rebase
做了什么操作呢?
首先, git
会把 feature1
分支里面的每个 commit
取消掉;
其次,把上面的操作临时保存成 patch
文件,存在 .git/rebase
目录下;
然后,把 feature1
分支更新到最新的 master
分支;
最后,把上面保存的 patch
文件应用到 feature1
分支上;
从 commit
记录我们可以看出来, feature1
分支是基于 hotfix
合并后的 master
,自然而然的成为了最领先的分支,而且没有 merge
的 commit
记录,是不是感觉很舒服了。
6.在 rebase
的过程中,也许会出现冲突 conflict
。在这种情况, git
会停止 rebase
并会让你去解决冲突。在解决完冲突后,用 git add
命令去更新这些内容。
注意,你无需执行 git-commit,只要执行 continue
git rebase --continue
这样 git
会继续应用余下的 patch
补丁文件。
7.在任何时候,我们都可以用 --abort
参数来终止 rebase
的行动,并且分支会回到 rebase
开始前的状态。
git rebase —abort
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK