实际工作场景

可能会遇到的工作流

  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. PTA 统计二叉树叶子结点个数

    6-2 统计二叉树叶子结点个数 (10 分)   本题要求实现一个函数,可统计二叉树的叶子结点个数. 函数接口定义: int LeafCount ( BiTree T); T是二叉树树根指针,函数Le ...

  2. Spring框架的介绍

    1.Spring框架的结构 由持久层.表现层.中间模块和测试层组成. 持久层:和数据接触.事务管理 表现层:对数据进行处理 中间模块:核心功能 测试层:用来测试完整度 核心功能介绍 1.1  控制反转 ...

  3. [GDKOI2021] 普及组 Day1 总结

    [ G D K O I 2021 ] 普 及 组 D a y 1 总 结 [GDKOI2021] 普及组 Day1 总结 [GDKOI2021]普及组Day1总结 长达3天的快乐GDKOI2021普及 ...

  4. 轻松理解 Spring AOP

    目录 Spring AOP 简介 Spring AOP 的基本概念 面向切面编程 AOP 的目的 AOP 术语和流程 术语 流程 五大通知执行顺序 例子 图例 实际的代码 使用 Spring AOP ...

  5. BUAA_2021_SE_Case_Analysis

    案例分析作业 项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 案例分析作业 我在这个课程的目标是 通过课程学习,完成第一个可以称之为"软 ...

  6. 前端缓存API请求数据

    1. 背景 在一些项目中,有时候会出现不同模块重复请求大量相同api接口的情况,特别是在一些功能相似的后台管理页面中.以下面这几个页面为例,每次进入页面都需要请求等大量重复的下拉框数据,下拉框数据短时 ...

  7. 【Azure 应用服务】备份网站时由于文件太大了,导致应用服务备份失败。如何解决?

    问题描述 备份网站时由于文件太大了,导致应用服务备份失败.如何解决呢? 问题分析 App Service (应用服务)的备份功能有10GB大小的限制,超过了是无法备份成功的并且该限制是无法扩大的.查看 ...

  8. JS 中一些高效的魔法运算符

    这两天有同事说我挺久没更新文章了,不过最近一段时间确实有点忙,一直在忙着两个活动中心的改版,没什么时间来更新文章.今天终于抽空可以写一写. JavaScript 现在每年都会发一个新版本,里面也会新增 ...

  9. G - River Hopscotch(二分)

    Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully ...

  10. D - The Frog's Games (二分)

    The annual Games in frogs' kingdom started again. The most famous game is the Ironfrog Triathlon. On ...