合并与变基

咱们正在开发某个项目,为了实现某个项目,咱们建立了分支task_113,正在这个分支上开展工做。这个时候收到反馈说有个很严重的bug须要当即处理。这个时候,你应该当即切换到线上分支,为这个bug创建新的分支issue_005,并在这个分支上修复它。在测试经过后,切换到线上分支来合并issue_005,最后将改动推到线上。而后切换回task_113上继续作新的需求。html

merge 合并

enter image description here

开始在task 113上工做:

在没开始作任务前,咱们仓库的结构如上。如今咱们开始建立task_113分支:git

$ git checkout -b task_113
Switched to a new branch 'task_113'
复制代码

这个时候咱们的git仓库结构以下: github

enter image description here

这个时候咱们在当前分支上作了些工做,而且提交到了版本库后,咱们的git结构以下: bash

enter image description here

收到紧急问题issue 005

这个时候咱们收到反馈的bug后,咱们当即切到master分支上,从master分支建立新的issue_005分支开始解决线上的bug:测试

在切换到master以前,须要确认全部修改已经提交到版本库中。ui

# 切换到master分支
git checkout master
Switched to branch 'master'

# 创建issue_005分支处理bug
git checkout -b issue_005
Switched to a new branch 'issue_005'
复制代码

下面的图是咱们如今git仓库的状态: spa

enter image description here
当issue_005分支上的修改测试完成后,咱们须要到master上将其合并。

git checkout master
Switched to branch 'master'

git merge issue_005
Updating 04132ad..86e4899
Fast-forward
 about.html | 1 +
 1 file changed, 1 insertion(+)
复制代码

Fast-forward: 表示的是在合并两个分支的时候,若是顺着一个分支走下去可以到达另外一个分支,那么Git在合并二者的时候,只会简单的将指针向前推动(指针右移),由于这种状况没有须要解决的分歧,这就叫作快进。3d

这个紧急问题处理完成后,咱们就能够将issue_005这个分支删除,由于咱们再也用不上它了。删除完成后,咱们继续回到task_113分支上继续咱们的工做:指针

git branch -d issue_005
Deleted branch issue_005 (was 86e4899).

git checkout task_113
Switched to branch 'task_113'

git commit -a -v -m 'update index.html[task 113]'
[task_113 76e0e88] update index.html[task 113]
 1 file changed, 1 insertion(+)
复制代码

这个时候咱们再来看看咱们的仓库结构: code

enter image description here

合并分支

task_113的需求咱们已经完成了,而且测试经过,这个时候咱们应该开始将它合并到master上准本发布到线上环境了。

git checkout master
Switched to branch 'master'

git merge task_113
Merge made by the 'recursive' strategy.
 index.html | 2 ++
 1 file changed, 2 insertions(+)
复制代码

此次的合并并无像上次合并那样,出现Fast-forward。由于master分支所在提交并非task_113分支所提交的直接祖先,在这种状况下,Git会使用两个分支末端所指的快照(c4和c5)以及这两个分支的共同祖先c2来一个简单的三方合并。合并事后的仓库结构为:

enter image description here

这个时候咱们再把task_113分支删除了就行了。咱们再看看git log --graph的结果:

enter image description here

从上图能够看出,和咱们画的结构图彻底一致,接下来咱们再介绍下另一种方法变基

变基

enter image description here
上图是咱们当前项目结构,若是这个时候用合并的方式来整合分支的话,最终结构为:
enter image description here
整合分支最容易的方法就是合并分支。它会把两个分支的最新快照以及两者之间共同祖先(若是能过快进的话,则直接快进)进行三方合并来生成新的快照。

而变基则是提取出C4中引入的补丁和修改,在C3的基础上应用一次。可使用rebase命令将提交的某一分支上的全部修改都移至另外一分支上。

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
复制代码

这个时候咱们回到master上,进行一次快进合并:

git merge work
Updating 3462092..ece0ba5
Fast-forward
 work.html | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 work.html
复制代码

合并事后,咱们的仓库结构为:

enter image description here

仍是用git log --graph来看看最后的结构:

enter image description here

其实变基和合并同样,最终都生成了一次新的提交,可是使用变基咱们让提交历史变得更加简介,你能够看到通过变基的分支的历史记录中,尽管开发工做是并行的,可是它们看起来就好像是穿行同样,提交历史是一条直线没有分叉。在简单的项目中,可能有点分叉也没什么,可是在一个多人维护的大型项目中,分叉多了项目的维护工做就会变得愈来愈复杂。

通常状况下咱们用变基也就是为了确保向远程分支推送时可以保持提交历史的简洁:当咱们在github上修复别人项目的bug时,咱们首先在本身的分支里开发,当开发完成后,你须要将你的代码变基到origin/master上,而后再向主项目提交修改。这样的话,该项目的维护者就再也不须要进行整合工做,而是快速合并便可。

变基的风险

使用变基的时候必定要记住一条规则:不要对在你的仓库外有副本的分支执行变基。 变基操做本质上是丢弃一些现有的提交,而后相应的建一些内容同样但实际不一样的提交。若是你将提交推送到远程仓库上,而其余人也从该仓库拉取提交并基于你的分支建立了新的分支作后续工做,这个时候你用git rebase命令从新整理了提交再此推送,其余人不得再也不次将它们手头的工做与你的提交进行整合,若是他们还要拉去并整合他们修改过的提交,整个开发工做就会变得异常的混乱。想一想去年美国由于同事频繁使用git push -f推送到远程分支而被同事枪击的新闻吧,这样你就能记住这条规则了。

相关文章
相关标签/搜索