Git-分支的建立与合并
举一个实际工作中可能会遇到的分支建立与合并的例子:
开发某个网站。
为实现某个新的需求,创建一个分支。
在这个分支上开展工作。
假设此时,你突然接到一个电话说有个很严重的问题需要紧急修补,那么可以按照下面的方式处理:返回到原先已经发布到生产服务器上的分支。
为这次紧急修补建立一个新分支,并在其中修复问题。
通过测试后,回到生产服务器所在的分支,将修补分支合并进来,然后再推送到生产服务器上。
切换到之前实现新需求的分支,继续工作。
分支的建立与切换
假设当前的工作状态是下面的样子:

现在,假设我们要修补#53问题,为此我们新建一个iss53分支并切换到该分支上
git checkout -b iss53
这相当于执行了下面两条命令
$ git branch iss53
$ git checkout iss53
经过若干次更新后,状态如下图:

此时我们接到一个电话,有紧急漏洞需要修补。此时我们需要切换到master分支。
但在切换之前,确保你所做的更改都已经提交,即你的暂存区是干净的。
$ git checkout master
Switched to branch 'master'
切换到master分支后,工作目录中的内容应该是和解决#53问题之前一样。然后,我们新建一个紧急修补分支hotfix并在其中修补漏洞。
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 3a0874c] fixed the broken email address
1 files changed, 1 deletion(-)

在我们确定修补成功后,需要回到master分支并把它合并起来然后发布到生产服务器。合并命令是git merge
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
README | 1 -
1 file changed, 1 deletion(-)
合并时出现的Fast-forward提示是由于当前的master分支是要并入的hotfix分支的直接上游,Git只需要移动master指针,因为这种单线的历史分支不存在任何需要解决的冲突,所以称这种合并为Fast-forward快进。
合并之后master和hotfix指向同一位置

由于补丁已经完成,所以hotfix已经完成了历史使命,使用git branch -d删掉分支
$ git branch -d hotfix
Deleted branch hotfix (was 3a0874c).
然后回到iss53继续我们的工作,
$ git checkout iss53
Switched to branch 'iss53'
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

在修补漏洞期间iss53并未受影响。
分支的合并
在问题 #53 相关的工作完成之后,可以合并回 master 分支。实际操作同前面合并 hotfix 分支差不多,只需回到 master 分支,运行 git merge 命令指定要合并进来的分支:
$ git checkout master
$ git merge iss53
Auto-merging README
Merge made by the 'recursive' strategy.
README | 1 +
1 file changed, 1 insertion(+)
请注意,这次合并操作的底层实现,并不同于之前 hotfix 的并入方式。因为这次你的开发历史是从更早的地方开始分叉的。由于当前 master 分支所指向的提交对象(C4)并不是 iss53 分支的直接祖先,Git 不得不进行一些额外处理。就此例而言,Git 会用两个分支的末端(C4 和 C5)以及它们的共同祖先(C2)进行一次简单的三方合并计算。

这次,Git 没有简单地把分支指针右移,而是对三方合并后的结果重新做一个新的快照,并自动创建一个指向它的提交对象(C6)。这个提交对象比较特殊,它有两个祖先(C4 和 C5)。
值得一提的是 Git 可以自己裁决哪个共同祖先才是最佳合并基础;这和 CVS 或 Subversion不同,它们需要开发者手工指定合并基础。所以此特性让 Git 的合并操作比其他系统都要简单不少。

合并后我们可以删除iss53分支
git branch -d iss53
遇到冲突时的合并
有时候合并操作并不会如此顺利。如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起,逻辑上说,这种问题只能由人来裁决。如果你在解决问题 #53 的过程中修改了 hotfix 中修改的部分,将得到类似下面的结果:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
上面的输出告诉你在index.html这个文件的合并有冲突,自动合并失败,你必须手动修复然后提交结果。
此时,用git status查看状态:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
任何包含未解决冲突的文件都会以未合并(unmerged)的状态列出。Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突,并用git add <file>来标记解决。可以看到此文件包含类似下面这样的部分:
<<<<<<< HEAD
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53
可以看到 ======= 隔开的上半部分,是 HEAD(即 master 分支,在运行 merge 命令时所切换到的分支)中的内容,下半部分是在 iss53 分支中的内容。解决冲突的办法无非是二者选其一或者由你亲自整合到一起。比如你可以通过把这段内容替换为下面这样来解决:
<div id="footer">
please contact us at email.support@github.com
</div>
这个解决方案各采纳了两个分支中的一部分内容,而且我还删除了 <<<<<<<,======= 和 >>>>>>> 这些行。在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决状态。
再运行git status确定所有冲突都解决后就可以用git commit来完成合并后的提交。
Git-分支的建立与合并的更多相关文章
- Git 分支 (二)合并
分支的新建与合并 让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流. 你将经历如下步骤:1. 开发某个网站.2. 为实现某个新的需求,创建一个分支.3. 在这个分支上开 ...
- git分支的创建与合并
在git中提倡使用分支,这就涉及到了分支的创建和合并.在git中我们的每次提交类似于一个链表,按照时间顺序向下排列,大约画了一个图,每个小圆圈代表一次提交,在git中有有一个主分支master,我们新 ...
- git 分支的创建、合并、删除
基本概念与命令 分支(branch):每次提交,Git都把提交的内容串成一条时间线,这条时间线就是一个分支 . git 分支的创建 git branch branchName git ...
- SVN中分支的建立与合并
转载 出处:http://yaozhong1988.blog.163.com/blog/static/141737885201162671635126/ 一. SVN分支的意义: 简单 ...
- Git 分支管理 创建与合并分支
分支在实际中有什么用呢? 假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了. 如果等代码全部写完再一次提交, ...
- git 分支的创建与合并
首先我们需要先创建一个新的dev分支,然后切换到dev分支: $ git checkout -b dev //命令语句 Switched to a new branch 'dev' //成功执行输出语 ...
- eclipse git 文件状态 及git分支的创建与合并与删除
eclipse里面Git文件状态及图标展示 EGit会出现如下图标,其对应状态及意义如下: 1)忽略[ ignored ]:仓库认为该文件不存在(如bin目录,不需要关注).通过右键Te ...
- 4.Git分支查看&创建&切换&合并
查看分支 git branch -v # 查看分支,*代表当前所在的分支 创建分支 git branch hot-fix # 创建一个hot-fix分支,然后使用-v查看 # 可以看到除了ma ...
- Git分支(5/5) -- 解决合并的冲突
如果两个分支上都对同一个文件进行了修改, 那么就有可能发生冲突. 首先创建一个分支, 并切换到该分支上: 然后修改index.html, 修改几个地方吧. 然后查看状态, 并commit: 然后切换到 ...
- Git分支管理及合并
Git分支管理 建立分支 git branch [name] 切换到分支 git checkout [name] 查看有哪些分支 git branch 比较分支 git diff [b ...
随机推荐
- 2015年蓝桥杯省赛A组c++第1题
/* 方程: a^2 + b^2 + c^2 = 1000 这个方程有整数解吗?有:a,b,c=6,8,30 就是一组解. 你能算出另一组合适的解吗? 请填写该解中最小的数字. 注意:你提交的应该是一 ...
- dispatch_barrier_async,加锁
dispatch_barrier_async用于文件读写,在写的时候,不允许进行读操作,在写操作完成才能进行读取操作,为了保证线程安全 加锁的方式: 1. barrier 2. NSLock 3. @ ...
- npm的源改成淘宝镜像
修改源地址为淘宝 NPM 镜像npm config set registry http://registry.npm.taobao.org/ 修改源地址为官方源npm config set regis ...
- debian下配置nginx缓存
root权限下 新建/usr/nginx/cache/webpages目录 在/etc/nginx/sites-available下找到自己所需配置的文件,打开文件后在开头加上proxy_cache_ ...
- Asp.net Mvc Ajax.BeginForm提交表单
之前Mvc中一直用Html.BeginForm提交表单,即如下: @using (Html.BeginForm("Add", "News", FormMetho ...
- es中filter和query的对比
1.filter与query示例PUT /company/employee/2{ "address": { "country": "china&quo ...
- 使用Jersey上传文件
采用jquery.form.js异步上传图片,并结合<form>表单 <script type="text/javascript"> //采用jquery. ...
- PinyinUtil
import java.util.HashSet;import java.util.Set;import java.util.regex.Matcher;import java.util.regex. ...
- Scala对class/object反射
近期有需求,要根据解析字符串,根据字符串的内容去调用方法.想到的基本就是使用反射.但是基本上能找到的资料,全没有讲scala的反射.只有零星点点的讲解.大部分都是用scala的语法写java反射最后翻 ...
- Ajax与跨域Ajax
Ajax 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上.对于传统的Web应用,一个简单操作需 ...