结合实际工作,我们设计项目分支,比如现在需要开发一个网站,为实现它的某个新的功能需要创建一个分支。
此时,遇到很严重的问题需要紧急修补,从而为其建立一个分支,并在测试通过之后,切换到线上分支,合并这个修补分支。
新建分支
项目所在分支情况

现在要解决问题追踪系统中的#53问题,可以建立一个分支,并在那个分支解决问题
$ git checkout -b iss53
Switched to a new branch "iss53"
上面命令等价于
$ git branch iss53
$ git checkout iss53

此时为解决#53问题,已经做了一些提交,则iss53分支将向前推进
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'

但是现在有紧急问题需要修改,而它无关53#问题,则可先切换回master分支。但是需要注意的是,在切换之前,先确定工作目录和暂存区有没有还没被提交的修改。
$ git checkout master
Switched to branch 'master'
现在针对紧急问题创建分支
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)

当运行测试,确保修改正确之后,可以将其合并到master分支,并部署到线上
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并的时候,看到如上的“快进”(fast-forward),这是由于当前master分支指向的提交是当前提交的上游,Git只需要简单的将指针向前移动。

当紧急问题解决之后,可以删除hotfix分支
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
并切换回此前的#53问题分支
$ 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(+)

由于hotfix分支所做的工作并没有包含到iss53分支,如果需要拉取hotfix所做的修改,可以git merge master 将master分支合并到iss53分支;或者是等到iss53分支完成再将其合并回master分支。
分支的合并
假设,已经修正#53问题,并打算将其合并到master分支
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)


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.
此时Git做了合并,但是没有自动创建新的合并提交,它会暂停下来,等待你去解决合并产生的冲突。
可以在合并冲突后的任何时刻,使用git status查看那些因包含合并冲突而处于未合并状态(unmerged)的文件
$ 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")
任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。Git会在有冲突的文件中加入标准的冲突解决标记,这样方便手动解决冲突
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
解决冲突方案是近保留其中一个分支的修改
<div id="footer">
please contact us at email.support@github.com
</div>
如果想使用图像化工具解决冲突,可以运行git mergetool ,它会启动一个合适的可视化合并工具
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
在解决完冲突文件,并暂存之后,即可git commit 完成合并提交
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#