内容简介:刚开始接触Git时,只会一些常规操作命令:pull、add、commit、push。毕业参加工作以后,在公司的大规模合作中,这时就迫切需要对git进行再了解。然后就系统地学习了git。终于对这些常用的命令知其然,知其所以然了,同时,也学习掌握了一些高级命令。其中rebase命令,让我觉得发现了git的新大陆。特此记录下相关知识,以做记录,也可以与大家相互学习交流。rebase,直接翻译过来就是变基,而这个命令就是这么人如其名。通过rebase命令,我们可以改变一串commits的基点(父commit)。首
刚开始接触Git时,只会一些常规操作命令:pull、add、commit、push。毕业参加工作以后,在公司的大规模合作中,这时就迫切需要对git进行再了解。然后就系统地学习了git。终于对这些常用的命令知其然,知其所以然了,同时,也学习掌握了一些高级命令。其中rebase命令,让我觉得发现了git的新大陆。特此记录下相关知识,以做记录,也可以与大家相互学习交流。
1 what is rebase
rebase,直接翻译过来就是变基,而这个命令就是这么人如其名。通过rebase命令,我们可以改变一串commits的基点(父commit)。首先我们先来操作一遍这个命令,看看效果就知道这个命令是干啥的了。
假设我们的git结构是这样子的。我们在commit3这个地方开出了一个分支branch1,然后在branch1分支上开发并提交了两个commit(6和7)。同时其他分支合并到master分支导致master分支多了两个提交(4和5)。
这时我们执行以下命令: ( 注: 此时的活动分支是branch1 )
(branch1) git rebase master
执行完命令后的git结构如下:
我们可以看到,在使用rebase命令之前,branch1和master的交叉点是commit3,这也是branch1的"基点"。通过执行 git rebase
命令后,branch1的"基点"就变成了5。从而改变了branch与master的交叉点,现在就是commit5。
rebase的工作原理是:Git会让我们想要移动的提交序列(commit6和commit7)在目标分支(master)上按照相同的顺序重新再现一遍。这就相当于我们为各个原提交做了个副本,它们拥有相同的修改集、同一个作者、日期以及注释信息。所以执行变基的相关commit是被复制了一份,上图也做了标识,而原先在branch1的commit6和commit7还是在历史版本中,我们可以通过commit的sha-1序列号来找到它们,只有在用gc命令执行垃圾回收之后(这个命令git会自动执行,以清理版本库),它们才会真正从版本库中消失。
rebase的执行步骤如下:
- 确定涉及到哪些提交 :确认活动分支(branch1)哪些提交不在目标分支上(master),这些提交(commit6和commit7)就是要进行变基的提交。
- 确认新的基点 :新的基点就是目标分支的最新提交,这里是commit5。
- 复制提交 :将需要变基的提交一次复制一份并创建新的提交(commit复制6和commit复制7),这里是按顺序来的
- 将活动分支重置 : 活动分支被移动到上述复制提交的顶部,在这里是commit复制7。
通过上面的演示已经原理讲解,大家应该对rebase有了一个基本的了解了。下面说说什么时候使用它。
2 什么时候使用rebase
- 净化历史 ,这也是使用rebase的最重要的原因,使用rebase变基后在合并代码,就会使得我们的主干分支(master)不会出现交叉情况,就是一条线往下走,这样就易于维护和管理。
- 移植分支,可以把一个分支上的一些提交移植到另一个分支上
- 通过rebase的高级用法,交互式变基,你可以对需要移动的分支(比如上面的commit6和commit7)进行修改、合并等等。
3 如何用rebase
- 合并开发分支到master,净化历史
当我们在功能分支上开发完一个功能时,我们需要将其合并到主分支上(master),继续拿上面的那个例子:
之前我们的做法是使用merge命令:
(branch1) git checkout master
(master) git merge branch1
执行完上述命令后,git结构如下:
合并以后会产生一个新的提交节点(commit7)。这样就产生了交叉,出现了"钻石链"。让master分支看起来很乱,也不易维护和管理。
下面看看使用rebase命令的效果。执行以下命令:
(branch1) git rebase master
注:rebase命令是在活动分支执行,而merge命令需要切换到你要合并的分支。所以rebase命令在branch1分支下执行,而merge命令在master分支下执行。这也是两者不同点之一
执行完上述命令,效果如下
这是branch1还没有合并到master。还需切换回master分支,执行merge命令。执行以下命令:
(branch1) git checkout master
(master) git merge branch1
至此,合并操作正式完成,看下效果:
上面的merge是快进合并(fast-faward),不会产生新的提交。如果需要产生新的提交(为了更好的记录追踪),可以使用--no-ff选项,在新版git中支持,旧版不一定支持: git merge --no-ff branch1
commit6和commit7后续会被清理掉。这样master分支就是一条线,清晰也易于维护和管理。
4 rebase的高级用法
rebase命令还有一些可选项,利用这些可选项,我们进行更复杂的操作。下面主要介绍两个--onto和--interactive。
使用--onto移植提交
在如下的git结构中,我们希望能将branch1分支和branch2分支同时合并到master。这是我们可以先将branch1分支中master没有的提交(commit6和commit7)合并到branch2,再通过上面的方法将branch2合并到master。这就是移植提交。可以将commit6和commit7合并到branch2中。
- 首先将活动分支切为branch1
git checkout branch1
- 执行移植操作
git rebase master --onto branch2 上面命令的意思是:将branch1分支中master分支没有的提交拷贝到branch2,执行后的结果如下:
这样就可以将branch1中的提交移植到branch2中。
使用--interactive进行更多操作给rebase加上--interactive选项,就变成了交互式变基,就是在变基(复制提交)过程中,会中途停止,然后给我们一些选择命令,让我们进行不同的操作。
举个例子,我们在feature分支开发一个功能,这其中进行了多次提交,产生多个commit。但我们希望当该分支合并到master时,只产生一个commit,这时就可以使用--interactive选项了,下面我们模拟操作下:
- 首先从master分支开出一个新的功能分支feature
git checkout -b feature
- 模拟开发,进行多次提交,这里模拟了三次提交 我们看看feature分支日志情况
提交了三个分支。再看下master分支情况:
master最新提交是"Merge branch 'test1'"
接下来,我们开始进行合并操作:
- 切换活动分支为feature
git checkout feature
- 执行交互式变基 -i 是--interactive的缩写
git rebase master -i 执行该命令后,变基操作会进入交互状态:
我们可以看到,上面列出了需要变基的所有提交,顺序从上之下,也是提交从前到后,先提交的commit显示在上面。接下来,就是交互式变基提供的7个命令:
- pick 也是默认,就是使用该commit,将其复制过去,正常变基
- reword 使用该提交,但是可以修改该提交的提交信息,当时用该命令是,接下来就会进入一个页面,让我们写信的提交信息。如果我们想修改那个commit的提交信息时,可以使用这个方法
- edit 使用该提交,并且变基中断,这时我们可以修改工作区文件,修改完以后
git add . => git commit --amend
进行重新提交。提交完后使用git rebase --continue
继续变基。如果你想修改某个提交,可以使用该方法 - squash 合并提交,它会合并到前面的提交中,然后让我们重新编辑提交信息,这也是我们要实现的。
- fixup 也是合并提交,但是没有然我们重新编辑提交信息,而是丢弃这些提交的提交信息
- drop 丢弃该提交,也就是该提交不会复制过去。
- exec 执行 shell 命令,貌似不知道有什么用
在了解了这些命令后,继续我们刚刚的任务,上面已经提到过,我们使用sqash命令合并提交,并重新编辑提交信息。
按字母i键进入编辑,因为是合并到前面的提交,我们把后面两个提交的命令改为squash,让这三个提交合并成一个,按ESC进入命令模式,再按ZZ保存。变基继续进入编辑提交信息页面
它会列表每个提交的之前的提交信息,我们重新编辑保存退出,变基就会继续完成。
没有冲突就会变基完成,如果有冲突,解决完冲突后,执行 git add . => git rebase --continue
继续变基即可。
变基完成并没有合并到master。
- 切换到master
git checkout master
- 进行合并操作
git merge feature 此时,任务完成,我们看看master日志 git log --graph
只有一个提交。如果在feature开发过程中master有新的提交。也不会出现交叉,就不演示了。
以上所述就是小编给大家介绍的《rebase — Git中一个强大的忍者》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python for Everyone
Cay S. Horstmann、Rance D. Necaise / John Wiley & Sons / 2013-4-26 / GBP 181.99
Cay Horstmann's" Python for Everyone "provides readers with step-by-step guidance, a feature that is immensely helpful for building confidence and providing an outline for the task at hand. "Problem S......一起来看看 《Python for Everyone》 这本书的介绍吧!