实际工作场景

可能会遇到的工作流

  1. 开发某个网站

  2. 为实现某个新的用户需求,创建一个分支

  3. 在这个分支上开展新工作

正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补,你将按照如下方式来处理:

  1. 切换到你的线上分支(production branch)

  2. 为这个紧急任务新建一个分支,并在其中修复它

  3. 在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支

  4. 切换回你最初工作的分支上,继续工作

新建分支

首先,我们假设你正在你的项目上工作,并且在 master 分支上已经有了一些提交。

为了解决问题,想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令

$ git checkout -b iss53
Switched to a new branch "iss53"

它是下面两条命令的简写

$ git branch iss53
$ git checkout iss53

创建一个新分支指针

在 iss53 分支上修改东西并提交,该分支就会不断的向前推进,因为已经 checkout 到该分支 (也就是说,HEAD 指针指向了 iss53 分支)

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'

紧急插入一个问题待修复

突然紧急插入一个问题需要修复,它可以不用和 iss53 分支混在一起,操作步骤

  1. git status 检查 iss53 分支下的工作区和暂存区是否有没提交的修改,不然会阻止 git 切换分支
  2. 切换至 master 分支
  3. 再新建一个 hotfix 分支并切换到它上,进行修复问题工作
$ git checkout master

Switched to branch 'master'

这个时候,Git 会让工作目录的内容会和 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 分支上

问题修复成功后,可以将 hotfix 分支合并回 master 分支来部署到线上

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)

什么是 fast-forward?

  1. 待合并的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后继, 因此 Git 会直接将指针向前移动
  2. 换句话说,当试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的冲突

现在,最新的修改已经在 master 分支所指向的提交快照中,可以提交发布修复了

删除 hotfix 分支,回到 iss53 分支继续工作

问题解决后,删除临时分支,因为不再需要它,而且 master 分支也指向同一个位置了

$ git branch -d hotfix
Deleted branch hotfix (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(+)

注意

  • 在 hotfix 分支上所做的工作并没有包含到 iss53 分支
  • 中如果你需要拉取 hotfix 所做的修改,可以使用 git merge master 命令将 master 分支合并入 iss53 分支,或者也可以等到 iss53 分支完成其使命,再将其合并回 master 分支

分支 iss53 合并

iss53 分支上工作已完成,回到 master 分支合并 iss53 的东西

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)

Merge made by the 'recursive' strategy. 通过递归策略合并

  • 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作
  • 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并
 

合并提交

和之前将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它,它的特别之处在于他有不止一个父提交

既然修改已经合并进来了,就不再需要 iss53 分支了

$ git branch -d iss53

遇到冲突时的分支合并

  • 如果在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们
  • 假设对 iss53 分支修改的内容和 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 会暂停下来,要手动解决合并产生的冲突
  • 使用 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

HEAD 所指示的版本

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>

这也是 master 分支下的文件内容,也是冲突的部分内容

iss53 分支的版本

<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

这是 iss53 分支下的文件内容,和 master 分支的内容冲突了,此时你必须二选一保留一个

保留 iss53 分支的版本

<div id="footer">
please contact us at email.support@github.com
</div>

<<<<<<< , ======= , 和 >>>>>>> 这些行需要删除哦

在解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决

图形化工具解决冲突

如果你想使用图形化工具来解决冲突,你可以运行 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 status 查看合并后的状态

$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge) Changes to be committed: modified: index.html

通过 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
#

Git 系列教程(12)- 分支的新建与合并的更多相关文章

  1. [译]Atlassian Git系列教程

    国庆期间把Atlassian的Git系列教程看完了.边看边翻译了相关文章. 原教程: https://www.atlassian.com/git/tutorials/ 我翻译的: git init g ...

  2. 3.2 Git 分支 - 分支的新建与合并

    分支的新建与合并 现在让我们来看一个简单的分支与合并的例子,实际工作中大体也会用到这样的工作流程: 开发某个网站. 为实现某个新的需求,创建一个分支. 在这个分支上开展工作. 假设此时,你突然接到一个 ...

  3. [转] Git 分支 - 分支的新建与合并

    http://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E ...

  4. Git 分支 - 分支的新建与合并

    转载自:https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB ...

  5. .2 Git 分支 - 分支的新建与合并

    分支的新建与合并 https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0% ...

  6. Git 系列教程(14)- 远程分支

    远程分支 远程引用是对远程仓库的引用(指针),包括分支.标签等等 你可以通过 git ls-remote <remote> 来显式地获得远程引用的完整列表 polo@B-J5D1MD6R- ...

  7. git 入门教程之分支总览

    分支就是一条独立的时间线,既有分支,必有主干,正如一棵树谈到树枝,必有树干一样的道理.我们先前对git 的全部操作默认都是在主干上进行的,这个主干也是一种特殊的分支,名为 master 分支. 无论是 ...

  8. Git在已有的分支上新建个人分支开发

    在Dev分支上新建一个分支(可以通过Git TE网页创建) 然后就可以从Source下拉列表中看到新建的分支(new_name1)了. 远程分支创建完成之后,就可以在本机上面使用Git GUI Her ...

  9. Git系列五之分支管理

    1.Git分支管理 分支即是平行空间,假设你在为某个手机系统研发拍照功能,代码已经完成了80%,但如果将这不完整的代码直接提交到git仓库中,又有可能影响到其他人的工作,此时我们便可以在该软件的项目之 ...

随机推荐

  1. C++覆盖,隐藏,重载

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...

  2. RocketMQ的安装配置:配置jdk环境,配置RocketMQ环境,配置集群环境,配置rocketmq-console

    RocketMQ的安装配置 演示虚拟机环境:Centos64-1 (D:\linuxMore\centos6_64) root / itcast : 固定IP 192.168.52.128 一,配置J ...

  3. Java例题_26 请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母。

    1 /*26 [程序 26 求星期] 2 题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母. 3 程序分析:用情况语句比较好,如果第一个字母一样,则判断用情 ...

  4. [题解] T'ill It's Over

    前言 线段树+网络最大流的建模题. 博客园食用更佳 题目大意 最初时有 \(n\) 个 \(1\) .给定 \(op\) . \(l\) ,其中, \(l\) 为操作次数上限.你有四个操作: 若 \( ...

  5. 「HTML+CSS」--自定义加载动画【005】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  6. OO UNIT 1 个人单元总结

    面向对象课程--第一单元个人总结 作业分析 第一次作业 概要 本次作业主要对简单幂函数的多项式进行求导计算,要点在于对输入字符串的处理,利用正则表达式匹配即可,并且需要对输出表达式的长度进行优化. 度 ...

  7. 软工案例分析作业-CSDN

    项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 案例分析作业要求 我在这个课程的目标是 提升软件开发能力与团队意识 这个作业在哪个具体方面帮助我实 ...

  8. 干掉 Feign,Spring Cloud Square 组件发布

    Spring Cloud Square 是什么 谈起 Spring Cloud 生态大家一定对 Feign 不陌生,如下图所示,Feign 可以把底层(okhttp.httpclient)Rest 的 ...

  9. Java并发的背景

    在操作系统中,并发是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行. 并发与操作系统的生命历程息息相关.进程的 ...

  10. 【SpringBoot源码分析】-Bean的加载过程

    -- 以下内容均基于2.1.8.RELEASE版本 在<SpringBoot启动过程的分析>系列文章中简要的对SpringBoot整体的启动流程作了梳理,但并未针对诸多细节进行分析.前面的 ...