rebase — Git中一个强大的忍者

栏目: 编程工具 · 发布时间: 5年前

内容简介:刚开始接触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)。

rebase — Git中一个强大的忍者

这时我们执行以下命令: ( 注: 此时的活动分支是branch1 )

(branch1) git rebase master

执行完命令后的git结构如下:

rebase — 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的执行步骤如下:

  1. 确定涉及到哪些提交 :确认活动分支(branch1)哪些提交不在目标分支上(master),这些提交(commit6和commit7)就是要进行变基的提交。
  2. 确认新的基点 :新的基点就是目标分支的最新提交,这里是commit5。
  3. 复制提交 :将需要变基的提交一次复制一份并创建新的提交(commit复制6和commit复制7),这里是按顺序来的
  4. 将活动分支重置 : 活动分支被移动到上述复制提交的顶部,在这里是commit复制7。

通过上面的演示已经原理讲解,大家应该对rebase有了一个基本的了解了。下面说说什么时候使用它。

2 什么时候使用rebase

  1. 净化历史 ,这也是使用rebase的最重要的原因,使用rebase变基后在合并代码,就会使得我们的主干分支(master)不会出现交叉情况,就是一条线往下走,这样就易于维护和管理。
  2. 移植分支,可以把一个分支上的一些提交移植到另一个分支上
  3. 通过rebase的高级用法,交互式变基,你可以对需要移动的分支(比如上面的commit6和commit7)进行修改、合并等等。

3 如何用rebase

  • 合并开发分支到master,净化历史

当我们在功能分支上开发完一个功能时,我们需要将其合并到主分支上(master),继续拿上面的那个例子:

rebase — Git中一个强大的忍者

之前我们的做法是使用merge命令:

(branch1) git checkout master
(master) git merge branch1

执行完上述命令后,git结构如下:

rebase — Git中一个强大的忍者

合并以后会产生一个新的提交节点(commit7)。这样就产生了交叉,出现了"钻石链"。让master分支看起来很乱,也不易维护和管理。

下面看看使用rebase命令的效果。执行以下命令:

(branch1) git rebase master

注:rebase命令是在活动分支执行,而merge命令需要切换到你要合并的分支。所以rebase命令在branch1分支下执行,而merge命令在master分支下执行。这也是两者不同点之一

执行完上述命令,效果如下

rebase — Git中一个强大的忍者

这是branch1还没有合并到master。还需切换回master分支,执行merge命令。执行以下命令:

(branch1) git checkout master
(master) git merge branch1

至此,合并操作正式完成,看下效果:

上面的merge是快进合并(fast-faward),不会产生新的提交。如果需要产生新的提交(为了更好的记录追踪),可以使用--no-ff选项,在新版git中支持,旧版不一定支持: git merge --no-ff branch1

rebase — Git中一个强大的忍者

commit6和commit7后续会被清理掉。这样master分支就是一条线,清晰也易于维护和管理。

4 rebase的高级用法

rebase命令还有一些可选项,利用这些可选项,我们进行更复杂的操作。下面主要介绍两个--onto和--interactive。

使用--onto移植提交

在如下的git结构中,我们希望能将branch1分支和branch2分支同时合并到master。这是我们可以先将branch1分支中master没有的提交(commit6和commit7)合并到branch2,再通过上面的方法将branch2合并到master。这就是移植提交。可以将commit6和commit7合并到branch2中。

rebase — Git中一个强大的忍者
  1. 首先将活动分支切为branch1
git checkout branch1
  1. 执行移植操作

git rebase master --onto branch2 上面命令的意思是:将branch1分支中master分支没有的提交拷贝到branch2,执行后的结果如下:

rebase — Git中一个强大的忍者

这样就可以将branch1中的提交移植到branch2中。

使用--interactive进行更多操作给rebase加上--interactive选项,就变成了交互式变基,就是在变基(复制提交)过程中,会中途停止,然后给我们一些选择命令,让我们进行不同的操作。

举个例子,我们在feature分支开发一个功能,这其中进行了多次提交,产生多个commit。但我们希望当该分支合并到master时,只产生一个commit,这时就可以使用--interactive选项了,下面我们模拟操作下:

  1. 首先从master分支开出一个新的功能分支feature
git checkout -b feature
  1. 模拟开发,进行多次提交,这里模拟了三次提交
    rebase — Git中一个强大的忍者
    我们看看feature分支日志情况
rebase — Git中一个强大的忍者

提交了三个分支。再看下master分支情况:

rebase — Git中一个强大的忍者

master最新提交是"Merge branch 'test1'"

接下来,我们开始进行合并操作:

  1. 切换活动分支为feature
git checkout feature
  1. 执行交互式变基 -i 是--interactive的缩写

git rebase master -i 执行该命令后,变基操作会进入交互状态:

rebase — Git中一个强大的忍者

我们可以看到,上面列出了需要变基的所有提交,顺序从上之下,也是提交从前到后,先提交的commit显示在上面。接下来,就是交互式变基提供的7个命令:

  • pick 也是默认,就是使用该commit,将其复制过去,正常变基
  • reword 使用该提交,但是可以修改该提交的提交信息,当时用该命令是,接下来就会进入一个页面,让我们写信的提交信息。如果我们想修改那个commit的提交信息时,可以使用这个方法
  • edit 使用该提交,并且变基中断,这时我们可以修改工作区文件,修改完以后 git add . => git commit --amend 进行重新提交。提交完后使用 git rebase --continue 继续变基。如果你想修改某个提交,可以使用该方法
  • squash 合并提交,它会合并到前面的提交中,然后让我们重新编辑提交信息,这也是我们要实现的。
  • fixup 也是合并提交,但是没有然我们重新编辑提交信息,而是丢弃这些提交的提交信息
  • drop 丢弃该提交,也就是该提交不会复制过去。
  • exec 执行 shell 命令,貌似不知道有什么用

在了解了这些命令后,继续我们刚刚的任务,上面已经提到过,我们使用sqash命令合并提交,并重新编辑提交信息。

rebase — Git中一个强大的忍者

按字母i键进入编辑,因为是合并到前面的提交,我们把后面两个提交的命令改为squash,让这三个提交合并成一个,按ESC进入命令模式,再按ZZ保存。变基继续进入编辑提交信息页面

rebase — Git中一个强大的忍者

它会列表每个提交的之前的提交信息,我们重新编辑保存退出,变基就会继续完成。

rebase — Git中一个强大的忍者

没有冲突就会变基完成,如果有冲突,解决完冲突后,执行 git add . => git rebase --continue 继续变基即可。

变基完成并没有合并到master。

  1. 切换到master
git checkout master
  1. 进行合并操作

git merge feature 此时,任务完成,我们看看master日志 git log --graph

rebase — Git中一个强大的忍者

只有一个提交。如果在feature开发过程中master有新的提交。也不会出现交叉,就不演示了。


以上所述就是小编给大家介绍的《rebase — Git中一个强大的忍者》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python for Everyone

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》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码