软件开发中,bug 就像家常便饭一样。有了 bug 就需要修复,在 Git 中,由于分支是如此的强大,所以,每个 bug 都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

当你接到一个修复一个代号 101 的 bug 的任务时,很自然地,你想创建一个分支 issue-101 来修复它,但是,等等,当前正在 dev 上进行的工作还没有提交:

$ git status
# On branch dev
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: hello.py
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readme.txt
#

并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需 1 天时间。但是,必须在两个小时内修复该 bug,怎么办?

幸好,Git 还提供了一个 stash 功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

$ git stash
Saved working directory and index state WIP on dev: 6224937 add merge
HEAD is now at 6224937 add merge

现在,用 git status 查看工作区,就是干净的(除非有没有被 Git 管理的文件),因此可以放心地创建分支来修复 bug。

首先确定要在哪个分支上修复 bug ,假定需要在 master 分支上修复,就从 master 创建临时分支:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
$ git checkout -b issue-101
Switched to a new branch 'issue-101'

现在修复 bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:

$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 cc17032] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)

修复完成后,切换到 master 分支,并完成合并,最后删除 issue-101 分支:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 2 commits.
$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
readme.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git branch -d issue-101
Deleted branch issue-101 (was cc17032).

太棒了,原计划两个小时的 bug 修复只花了 5 分钟!现在,是时候接着回到 dev 分支干活了!

$ git checkout dev
Switched to branch 'dev'
$ git status
# On branch dev
nothing to commit (working directory clean)

工作区是干净的,刚才的工作现场存到哪去了?用 git stash list 命令看看:

$ git stash list
stash@{0}: WIP on dev: 6224937 add merge

工作现场还在,Git 把 stash 内容存在某个地方了,但是需要恢复一下,有两个办法:

一是用 git stash apply 恢复,但是恢复后,stash 内容并不删除,你需要用 git stash drop 来删除;

另一种方式是用 git stash pop,恢复的同时把 stash 内容也删了:

$ git stash pop
# On branch dev
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: hello.py
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readme.txt
#
Dropped refs/stash@{0} (f624f8e5f082f2df2bed8a4e09c12fd2943bdd40)

再用 git stash list 查看,就看不到任何 stash 内容了:

$ git stash list

你可以多次 stash,恢复的时候,先用 git stash list 查看,然后恢复指定的 stash,用命令:

$ git stash apply stash@{0}

小结

修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除;

当手头工作没有完成时,先把工作现场 git stash 一下,然后去修复 bug,修复后,再 git stash pop,回到工作现场。


【网友 留言】

留言1:不理解[工作只进行到一半,还没法提交]这句话。为什么不能先在 dev 上提交,然后转去 master 上修 bug,最后转回 dev 上继续写?求解答。

答1:如果只有你一个人开发没问题。但是多人合作时,你向 dev 提交一个尚未完成的 commit,理论来说这个提交是错误的,如果有别人再下载 dev 分支再去做工作,这就是埋雷了。

答2:多人的话不PUSH是不是就行了?直接commit 上去也不会丢的吧?

答3:但是你后续开发总归还是要 PUSH 的,这时候你之前没有 PUSH 的 commit 会一起被 PUSH 到远程。虽说不是必然出问题,但终究存在隐患。

答4:我感觉 通过分支切换也可以完全不使用 stash 这个功能(个人见解):

关键是当你在某个分支上(比如 dev)还有很多东西没有提交(要切换分支必须 commit 之后)你如果因为另外一个分支需要紧急 bug 修复 而把你现在修改的文件(一般都不止一个)提交的话 之后 你再回来你需要再去查看你的那些代码是完成了一半就提交了的,哪些是真正提交了的。我感觉提交最起码就是你感觉你的代码已经完成一个功能,可以上传了才提交。

答5:因为没完成的工作提交后会影响到其他人。可能你会说,那就不提交了,反正不在一个分支。听着是这么个理,但是请注意不管你现在在哪个分支,工作区和暂存区都是同一个,所以在修复bug时会清掉之前的工作内容

留言2:既然要删除分支,那还加 --no-ff 参数干嘛?

答1:可以查看历史啊,这样就可以回溯了。

如果你实验一下的话,会发现用 ff 模式,删除分之后是没有历史并且无法回溯的。

以上是我的个人见解,仅供参考啊。

留言3:解封时会有提示冲突,需手动改一次文件

概览:master 合并(merge)解决好的 bug 后,切换到 dev 分支,先不要解封 dev(git stash pop),先合并 master,获取里面的 bug 方案后,再解封。解封时会有提示冲突,需手动改一次文件。

1:在 dev 下正常开发中,说有 1 个 bug 要解决,首先我需要把 dev 分支封存 stash

2:在 master 下新建一个 issue-101 分支,解决 bug,成功后

3:在 master 下合并 issue-101 分支

4:在 dev 下合并 master, 这样才同步了里面的 bug 解决方案

5:解封 dev (git stash pop),系统自动合并 & 提示有冲突,因为封存前 dev 写了东西,此时去文件里手动改冲突

6:继续开发 dev,最后 add,commit

7:在 master 下合并最后完成的 dev

代码过程如下:

1:$ git stash

2:$ git checkout master

$ git checkout -b issue-101

// 去文件里修 bug

$ git add README.md

$ git commit -m "fix-issue-101"

3:$ git checkout master

$ git merge --no-ff -m "m-merge-issue-101" issue-101

$ git branch -d issue-101

4:$ git checkout dev

$ git merge --no-ff -m "dev-merge-m" master

5:$ git stash pop

// 提示冲突,去文件手动改正

Auto-merging README.md CONFLICT (content): Merge conflict in README.md

6:// 继续开发 ... ... ,完成后一并提交

$ git add README.md

$ git commit -m "fixconflict & append something"

7:$ git checkout master

$ git merge --no-ff -m "m-merge-dev" dev

$ git branch -d dev

摘自:

http://www.liaoxuefeng.com/wiki/0013739516305929606d


实战心得:

上面是 廖老师 关于 修复分支 bug 的一些参考,在实际项目中,我不是通过“新建临时 bug 分支,然后删除该分支”方式处理的,参考如下:

项目 有 2 个分支:master 和 develop

1、先利用 PhpStorm 自带的“Shelve Changes”功能,保存当前 develop 分支的现场;

2、切换至 master 分支,修复 bug 并提交(commit);

3、切换至 develop 分支,合并 master 分支,获取里面的 bug 方案;

4、再后来,要发布新的正式版本了,切换至 master 分支,合并 develop 分支,然后推送(push)到远程 master 分支 即可。

附:Git 修复 bug 切换分支时,如何保存修改过的代码(即如何保存现场)?

[廖雪峰] Git 分支管理(2):Bug 分支的更多相关文章

  1. git分支管理之Bug分支

    软件开发中,bug就像家常便饭一样.有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除. 当你接到一个修复一 ...

  2. 廖雪峰 Git 教程 + Git-Cheat-Sheet 学习总结

    廖雪峰 Git 教程 + Git-Cheat-Sheet 学习总结 本教程主要是个人的 Git 学习总结. 主要参考博客: 廖雪峰 Git 教程 Git-Cheat-Sheet 文章目录 廖雪峰 Gi ...

  3. 廖雪峰 Git教程学习笔记 原文 http://www.liaoxuefeng.com/

    一 .集中式与分布式        先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推 ...

  4. 《廖雪峰Git教程》学习笔记

    原文链接 一.创建版本库 ①初始化一个Git仓库:git init ②添加文件到Git仓库:1.git add<file> ;  2.git commit 二.时光机穿梭 ①查看工作区状态 ...

  5. 廖雪峰Git入门教程

    廖雪峰Git入门教程  2018-05-24 23:05:11     0     0     0 https://www.liaoxuefeng.com/wiki/00137395163059296 ...

  6. [廖雪峰] Git 分支管理(3):分支管理策略

    通常,合并分支时,如果可能,Git 会用 Fast forward 模式,但这种模式下,删除分支后,会丢掉分支信息. 如果要强制 禁用 Fast forward 模式,Git 就会在 merge 时生 ...

  7. [廖雪峰] Git 分支管理(1):创建与合并分支(HEAD、master、dev、指针)

    每次提交,Git 都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在 Git 里,这个分支叫主分支,即 master 分支.HEAD 严格来说不是指向提交,而是指向 mas ...

  8. Git-第五篇廖雪峰Git教程学习笔记(4)分支

    1.一开始,只有一个主分支(master),HEAD指向Master,而Master指向主分支.现在我们创建dev分支. lfy@lfy-PC MINGW64 /c/fyliu/lfyTemp/git ...

  9. Git----分支管理之bug分支04

    ---恢复内容开始--- 软件开发中,bug就像家常便饭一样,有了bug就需要修复,在Git中,由于分支是如此强大,所以,每个bug都可以通过一个临时分支来修复,修复后,合并分支,然后将临时分支删除. ...

随机推荐

  1. FinalShell 推荐

    FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工具,充分满足开发,运维需求. 用户QQ群 342045988 Windows版下载地址:http:/ ...

  2. 【Python】Flask系列-cookie和session笔记

    cookie: 1.cookie出现的原因:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了 ...

  3. 【Python】Flask系列-模板笔记

    Jinja2模板 Jinja2模板传参 如何渲染模板: 模板放在templates文件夹下 从flask中导入render_template函数. 在视图函数中,使用render_template函数 ...

  4. ApiCloud利用NVTabBar模块快速搭建起APP的框架

    废话不说,直接上代码 模块地址:https://docs.apicloud.com/Client-API/Nav-Menu/NVTabBar 代码实例: <!doctype html> & ...

  5. Python学习一|anaconda的安装问题以及Python语言的特点

    安装时遇到的问题 安装anaconda3.0到D盘之后,配置好两个环境变量:D:\anaconda和D:\anaconda\Scripts.发现在命令行中执行python指令可以,但conda指令却是 ...

  6. 2018-11-3& maven

    https://www.cnblogs.com/clsn/p/7944116.html#auto_id_10 http://www.runoob.com/maven/maven-creating-pr ...

  7. C# Message类的属性Msg所关联的消息ID

    C# Message类的属性Msg所关联的消息ID   https://msdn.microsoft.com/en-us/library/windows/desktop/ms645606(v=vs.8 ...

  8. SQL Server 2

    一.创建数据表 1.连接服务器: 2.右击“表”节点,选择“新建表”,即: 3.在弹出的“表设计器”中,输入表的列名.选择的数据类型及是否允许为空,即: 二.导入数据表 1.右击表名,弹出菜单,选择“ ...

  9. 【LOJ】#2076. 「JSOI2016」炸弹攻击

    题解 我冷静一下,话说如果去掉建筑和R的限制好像是模拟退火吧 然后开始写模拟退火了,起始点就随机一个敌人作为起始点 没对着数据写了一下获得了70pts,感到美滋滋 然后对着数据卡了很久--发现有个数据 ...

  10. matlab中等间距坐标距离表示不等间距数据值,以及延伸

    1.问题 平时只是用了一下plot的简单画图. x轴或者y轴的大小比例都是按照系统自动的生成. 但是如果出现巨大的比例的时候,如何保证在另一个轴上可以同等机会展示结果呢? 2.程序 这里是自己书写的程 ...