学习Git过程中缺乏实践?不如来玩一玩这款Git闯关游戏,通过git命令来闯关。玩着玩着就学会了Git,美滋滋!
githug
githug 是用Ruby开发为了帮助学习使用git的一个闯关游戏。和我之前推荐的学习Linux命令的Bandit游戏有点像。
其Github地址:https://github.com/Gazler/githug
安装过程也比较简单,首先安装好基本的Ruby环境(1.8.7)以上
因为国内可能会遇到用gem安装相关包因为https网络问题报错的情况,如果出现Unable to download data from https://rubygems.org/
这样的报错信息
可以通过如下方式解决1
2sudo gem sources -r https://rubygems.org
sudo gem sources -a http://rubygems.org
当然安装完以后也别忘了设置回来1
2sudo gem sources -r http://rubygems.org
sudo gem sources -a https://rubygems.org
然后进行安装:1
sudo gem install githug
安装完成以后运行githug
会提示创建相关的文件夹,回复y
就行了。
githug有4个基本命令:1
2
3
4play - 默认命令,查看当前状态和题目
hint - 给你当前level的一些提示
reset - 重新开始当前关卡
levels - 列出所有关卡
通过题解
有一些关卡比较简单,选取一些我觉得有点意思的关卡给出题解吧。
20 commit_in_futue
使用一个未来的时间作为提交,提交的时候指定–date选项,能够自定义提交的时间
1 | $ git commit -m "future commit" --date=12.12.2018T22:00:00 |
21 reset
git reset 常用来进行版本回推。要了解reset
命令首先要了解git中的三棵树:HEAD
:是当前分支引用的指针,它总是指向该分支上的最后一次提交。 这表示 HEAD 将是下一次提交的父结点。暂存区(Index)
:预期的下一次提交工作区
:git 实际管理的文件的目录
reset
命令以一种简单可预见的方式直接操纵三棵树,它做了三个基本操作:移动 HAED,重置索引,重置工作目录。实际上 reset 是以特定的顺序来重写三棵树,并在指定相应选项时停止:
- 移动 HEAD 分支的指向 (若指定了 –soft,则到此停止)
- 使索引看起来像 HEAD (–mixed,默认到此停止)
- 使工作目录看起来像索引 (若指定了 –hard,则进行这一步)
1 | git reset to_commit_second.rb |
22 reset_soft
使用 reset 命令的 –soft 选项
1 | git reset --soft HEAD~ |
23 checkout_file
checkout 作用于文件的时候,会将文件从当前HEAD中检出,即让当前工作区的文件变成HEAD中的样子,命令格式为git checkout [-q] [<commit>] [--] <paths>...
1 | git checkout config.rb |
30 blame
可以通过 git blame
命令查看项目中具体哪一行代码是谁写的,什么时候引入的。
1 | git blame config.rb |
33 checkout_tag
检出到指定标签,通过checkout
命令实现,能够创建一个临时分支指向tag所在的提交
1 | git checkout v1.2 |
34 checkout_tag_over_branch
有的时候会遇到标签和分支的名字一样的情况,通过在前面添加前缀tags/
来指定是tag的名字
1 | git checkout tags/v1.2 |
35 branch_at
检出指定提交到一个新的命名分支
1 | git checkout -b test_branch HEAD~ |
40 rebase
rebase命令可以用来整合来自不同分支
如上图所示,提取在 C4 中引入的补丁和修改,然后在 C3 的基础上再应用一次。在 Git 中,这种操作就叫做 变基
git rebase [<upstream> [<branch>]
命令将upstream的修改在branch上再应用一次
1 | git checkout feature |
41 rebase-onto
在对两个分支进行变基时,所生成的“重演”并不一定要在目标分支上应用,你也可以指定另外的一个分支进行应用。就像 从一个特性分支里再分出一个特性分支的提交历史 中的例子这样。
$ git rebase --onto master server client
以上命令的意思是:“取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然后把它们在 master 分支上重演一遍”。
当master 和server 一致的时候,只需要写一个
1 | git rebase --onto master wrong_branch |
42 repack
git repack 对松散对象进行打包,凡是有引用关联的对象都被打在包里,未被关联的对象仍旧以松散对象的形式保存
1 | git repack |
43 cherry-pick
应用某一个提交的修改到当前分支
1 | git checkout new-feature |
45 rename commit
当涉及提交修改时,应该想到 git rebase -i
命令,它接受可以一个参数(提交的哈希值),它将罗列出此提交之后的所有提交,将此提交作为一个root commit。用途为修改提交历史,其后跟一个某一条提交日志的哈希值,表示要修改这条日志之前的提交历史。
输入命令以后,会将提交从前到后显示。每一行的前面有一个命令词,表示对此次更新执行什么操作。
类似下面这种:
1 | pick 06973a3 First coommit |
前面的命令有以下几种:
- “pick”,表示执行此次提交;
- “reword”,表示执行此次提交,但要修改备注内容;
- “edit”,表示可以修改此次提交,比如再追加文件或修改文件;
- “squash”,表示把此次提交的内容合并到上次提交中,备注内容也合并到上次提交中;
- “fixup”,和 “squash” 类似,但会丢弃掉此次备注内容;
- “exec”,执行命令行下的命令;
- “drop”,删除此次提交。
这一关是需要把第2次提交错误额comment修改过来,所以对第二次提交执行reword并修改备注就行了
46 squash
把多次修改合并成一次,这里用到的还是上面的git rebase -i
的命令,只不过是将后面动作命令都变成squash
47 merge_squash
为了把分支的多次提交合并为主干上的一次提交,可以在merge命令后面加一个 squash 参数
git merge branch-name --squash
过关命令:1
2git merge long-feature-branch --squash
git commit -m "comment"
48 reorder
你提交了几次但是提交顺序多了,想把顺序换一下,这里用到的还是git rebase -i
命令。需要把几次提交的顺序更换一下即可。
49 bisect
在程序持续迭代的过程中不免会引入 bug,除了定位 bug 的代码片断,我们还想知道 bug 是在什么时间被引入的,这时就可以借助 Git 提供的 bisect 工具来查找是哪次提交引入了 bug。bisect 是用二分法来查找的,就像用二分查找法查找数组元素那样。
其查找流程也比较简单,首先确定查找的commit范围,然后在每一次二分查找时给出程序执行是否正确的判断。这个时候bisect就会自动进行二分查找。
1 | $ git bisect start |
50 stage_lines
用 git add
命令可以把文件添加到暂存区,但如果你不想把文件中的全部修改都提交到暂存区,或者说你只想把文件中的部分修改提交到缓存区,那么你需要加上edit
参数
这时 Git 会自动打开文本编辑器,编辑的内容就是 git diff
命令的结果,这时你就可以编辑2个文件之间的差异,只保留要提交到暂存区的差异,而删除不需要提交到暂存区的差异,然后保存退出,Git 就会按你编辑过的差异把相应的内容提交到暂存区。
1 | git add file-name --edit |
51 find_old_branch
使用git reflog
可以查看历史所在的分支和提交在哪里
52 revert
git revert
命令能够对某一次提交执行逆操作,这适用于某次提交出现问题的情况,添加--no-edit
能够让系统自动生成备注
1 | git log |
55 submodule
如果你想把别人的仓库代码作为自己项目一个库来使用,可以采用模块化的思路,把这个库作为模块进行管理。Git 专门提供了相应的工具,用如下命令把第三方仓库作为模块引入:
git submodule add module-url
1 | git submodule add https://github.com/jackmaney/githug-include-me |