这是一个系列文章,介绍学习 Git 的一个小游戏 - githug,若是你是第一次看到,请先阅读:
闯过这 54 关,点亮你的 Git 技能树
闯过这 54 关,点亮你的 Git 技能树(一)
闯过这 54 关,点亮你的 Git 技能树(二)
闯过这 54 关,点亮你的 Git 技能树(三)
闯过这 54 关,点亮你的 Git 技能树(四)git
没想到第四弹在「开发者头条」上得到了 300 多个赞。
看来你们对这个小游戏挺感兴趣的,并且还有很多朋友在促更,今天就让咱们一气呵成打通最后的 14 关吧。程序员
一样,如对任何命令使用有疑问请看第一篇里的推荐教程,也欢迎在下面留言,我会尽力提供帮助的。工具
项目时间长了,git
仓库会慢慢变大,如何优化?
这个场景平常不多用到,并且不是必须用的,因此没什么概念。来看一下提示吧!
打开帮助以后输入 /redundant
搜索关键字,一下就找到了一个 -d
的参数。post
有一次,我正在一个特性分支上开发一个功能,提交了几回代码,就在准备结束合并代码的时候,而后产品经理说这个需求不用作了。
我强压下内心奔腾的一万只草泥马,准备删除这个分支,但在删除以前想到有一个 commit 是对一个工具类的修改,仍是有用的。
这是我就须要从特性分支上把这个 commit 摘出来,合到 master 分支上,再删除特性分支。
这个题目就是相似的场景,先来看看特性分支叫什么,而后找到须要「摘」出来的那个 commit:
查看了一下 log
命令的帮助,发现能够指定分支,这样就省去了 checkout 到 new-feature 分支的步骤。
上图中最后的一次提交就是咱们须要「摘」出来的,复制它的 Hash。
顺利过关!学习
咱们在开发的过程当中,为了避免影响当前正在作的事情,会把一些不那么紧急的任务使用 TODO
注释在代码里,现代的 IDE 都能帮咱们识别这些注释并在一个单独的窗口中罗列出来。
固然,不借助 IDE,光凭系统命令或 git 命令也是能够作到的。测试
查看 log,git log --oneline
,能够看到中间的 commit message 有一个拼写错误。
看一下提示,能够在 rebase 的时候指定 -i
参数:
查看一下帮助就知道是 interactive
的意思:
在打开的 Vim 窗口中将第一行的 pick
改成 r
,表示:使用 commit,而且修改 commit message。
修正拼写错误的 coommit
。优化
当我使用 TDD 方式进行开发,会进行很是频繁小步的提交,这样在其余同事看来就缺少完整性,也会增长后续维护成本。
因此 git 让我能够在 push 到远程仓库以前,对 commit 历史进行修改合并,把多个 commit 合并成一个。
用 git log --oneline
看一下提交记录:
从提交记录能够看出,它提示咱们将最后三个 commit 都合并到第二个 commit - Adding README 中。
接着执行 git rebase -i HEAD~4
:
第一个 commit 为 pick
,后三个改成 s
,意思是使用这个 commit,但将它合并到前一个 commit 中去。
保存退出,会提示咱们编辑 commit message,再次保存退出后,查看一下提交记录:spa
题目要求在 merge 特性分支时,把全部的新提交合并成一个,先来看看 master 分支当成的状态:git log --oneline
:
再看一下 git log long-feature-branch --oneline
:翻译
完整过关命令以下:3d
最后 master 分支情况如图,只用一个 commit,包含了 long-feature-branch
全部的修改:
提交顺序错乱时,也可使用 git rebase -i
进行调整。
先看看 Log,最后两个提交颠倒了位置:
执行 git rebase -i HEAD~2
,将两行 pick xxx 代码交换位置便可。
看一下历史:
代码中不知道何时引入了 bug,不过不要紧,咱们有自动化测试。
咱们能够不断手工 checkout 到某个 commit,结合二分法查找快速定位到引入 bug 的那一个 commit。
不过这种纯手工重复的事情,已经包含在 git 的命令中了,就是 bisect
读一下 git help bisect
,能够找到这个例子:
咱们知道 HEAD 的代码是有问题的,而第一个 commit 的代码是没问题的。
经过 git log
得到第一个 commit 的 Hash,就能够执行 bisect 命令:
红线部分已经清楚地告诉咱们是哪一个 commit 引入的 bug 了。
有时开发了一个特性没提交,接着又开发了另外一个特性。
做为一个自律的程序员,应该是要分两次提交的,若是修改的是不一样的文件,那能够轻松地经过 add 不一样的文件进行两次提交。
但此次好巧不巧的是竟然修改了同一个文件,怎么办?看看提示:
原来 git add 的最小粒度不是「文件」,而是 hunk(代码块)。git help add
而后查找 hunk
:
执行以下命令:
Git 会让咱们有机会选择对每个 hunk 作什么样的操做。这里修改同一个位置,在一个 hunk 里,根据提示咱们还要输入 e
手工编辑 hunk。
将第 5 行删除,保存退出,再看当前状态:git diff --cached
:
git diff
:
目的达到了,过关:
正在特性分支上开发一个功能,被头儿叫去修了一个紧急的 bug,修完后发现:妈蛋,那个特性分支叫啥?忘记了!
固然,做为一个自律的程序员,通常是否是出现这样的场景的。
这种状况说明分支命名太没有规律,或者分支太多,否则能够经过 git branch
看一下,也能很快找到特性分支。
先看一下提示吧:
哦,原来有个命令叫 git reflog
,来看看帮助文档 - git help reflog
,看起来这个命令很是强大,不过咱们这里只用到简单用法就能够了:
上图中第二行就显示了咱们以前工做的特性分支。
有时代码 push 到远程仓库后发现某一块代码有问题,咱们能够经过 revert
命令将特定 commit 彻底恢复。
首先咱们要找到须要 revert 的 commit 的 hash:
彻底过程以下:
刚刚把最新的一次提交给毫无保留的扔掉,立刻就改了主意,怎么办?世界上有后悔药吗?
有的,只要进行 git 版本控制的一切都能找得回来。看下提示先:
提示说被咱们抛弃的那个 commit 像孤魂野鬼同样在外游荡,尚未被鬼差送入地狱,咱们还能经过 git reflog
找到它的代号。
找到它的 Hash 后就经过 cherry-pick 将它找回来:
冲突合并是使用版本控制很是常见的了,竟然在这么靠后的位置才出来。
编辑冲突的文件 poem.txt,删除 Git 添加的标识冲突的行。
别忘了,还要 git add poem.txt
而后 git commit
。
submodule 是 Git 组织大型项目的一种方式,一般可把第三方依赖做为 submodule 包含进来,这个 submodule 自己也是一个独立的 Git 项目。
最后这一关并不是测试使用 GitHub 的能力,而是指望你们贡献代码,包括增长更多关卡,修复 Bug 或者完善文档。
我当初是准备翻译中文版,结果工做量不小,拖的过久最后不了了之了。
但愿你能对开源社区贡献本身的一分力量!哪怕 Star
一下也是对做者莫大的鼓舞!
终于完结了,谢谢你这么耐心一路跟着操练下来,但愿你也像我同样从这个游戏里收获不少。
若是你喜欢这个系列文章,将它们分享给你的同事好友,也是对我最大的鼓励!
若是有什么意见反馈,欢迎评论留言,我必定回复。
若是你发现有好的学习某技术的游戏或教程,欢迎来到「软件匠艺社区」 与你们分享!