前言
新公司的git规范对rebase的使用大大增加,之前都是merge一把刷子干的,而为了能够更好的查看git记录树,可视化工具sourcetree是不错的选择,故而整理下常见的使用方法。
撤销相关
撤销是比较重要的操作,而且容易出错,故而先整理这一块。
未暂存前撤销
在没有git add之前,先撤销。通过丢弃功能即可:

已暂存,未提交前撤销
已经add了,但是没有commit的话,直接取消暂存即可。 
已提交,未推送远端前撤销
如果已经commit,但是没有push到远端。有两种方式,第一种是通过选择要回滚到的commit,右键 重置当前分支到此次提交,这种方式会回滚到add之前,也就是所有本次修改的文件内容均得以保存: 
如果是想直接放弃所有的这次commit内容,则选择要回滚到的commit,右键 回滚提交,但是这种情况容易产生冲突,所以也是不太建议的。完全可以通过上面的方式,再参考未暂存前撤销的方式,完成回滚操作。 
已推送远端后撤销
如果已经push到远端了,又想撤销。首先右键要去的commit,重置当前分支到此次提交,

然后打开命令行模式,执行git push -f ,强制将内容推到远端,最后把本地未暂存的改动全部丢弃(或者在重置当前分支到此此提交时使用强行合并)即可。 
可以看到多余的commit已经没有了。

rebase相关
rebase两个作用,一个是将本分支多个commit进行合并或者其他美化操作,一个是将不同分支直接进行合并(但是不像merge那样会让分支树很混乱)。在sourcetree,rebase叫做变基。但是需要注意,rebase只能用在个人分支,不要用在公共分支!再就是已经push后的分支是无效的,请直接使用已推送远端后撤销的方式来撤销。
先说第一种
本分支commit合并
有时候我们的commit信息不好看,比如这种:

我们想把这几个优化下,把2和3的commit合并:我们选择右键交互式变基:
 然后选中第一个,点击用此前的squash,只到所有commit合并到一个,再点击后编辑一下commit的信息,确定即可。

最后发现分支树已优化完毕: 
跨分支变基
在test2分支,想把test1分支的代码并过来。
本地分支rebase本地分支
有以下几种情况,第一种是test1,test2都是本地分支,没有远端。 
这种情况下自己处于test1分支,然后右键test2分支,变基即可。 
本地分支rebase远程不同分支
现在test2是个远程分支,而test3的新的本地分支,我们想把test2的内容rebase到test3中。  我们还是先切到test3分支,右键test2分支,变基即可。 
本地分支rebase远程相同分支
如果多人在同一分支开发,使用拉取也就是git pull = git fetch + git merge ,这样会多一条merge的记录,而使用git pull -r = git fetch + git rebase 。这样就是走的rebase的流程。
比如目前的test4分支,可以看到本地的和远程的不一样:
这时如果使用拉取+推送的话,就会多一条merge的记录。
 这个时候可以通过在本地test4分支,右键远程test4分支,变基,再去推送即可。 
远程分支rebase远程分支
假设我们现在有了test4分支,并且已经push到远端了,这个时候又想把远端的test2分支的内容rebase过来。  我们还是先切到test4分支,然后右键点击test2的变基。(还有后续流程):  你会发现多了拉取和推送,但是切记千万不要点击(原因是rebase产生了新的commitid,你本地的tes4和远端的已不再一样了,如果拉取相当于git pull而不是git pull -r,所以会造成多一次相同提交和merge记录)。这种情况下直接将通过命令行git push -f 强制推送即可。
 可以看到结果又好了。
这也是为什么不要在公共分支(有远端的分支)轻易使用rebase的原因了,因为你会修改别人的提交记录!!
冲突处理
有时候rebase时会发生冲突,比如test5和test6改了同一个文件的同一行,这个时候我在test6上对test5进行变基。

sourcetree会提示你有冲突并需要解决:  这个时候需要去编辑器内解决冲突,然后暂存(git add .),再进行命令行操作git rebase --continue ,来完成正常的rebase流程。  这样就又正常了: 
|