githug游戏攻略

Github我知道是什么,那么Githug这又是个啥?其实Githug是一个练习Git技能的命令行游戏,这里是它的GitHub仓库

安装方法

Github需要事先安装Ruby 1.8.7+,Ubuntu自带的Ruby版本就是1.9.3,所以可以直接通过以下命令安装。Windows系统或者Mac系统的小伙伴可以查看上述GitHub地址,来获取更加详细的安装方法。

$ gem install githug

安装完成后,到你想要的目录下,输入githug命令,按要求创建一个git_hug目录,进入该目录,即可开始游戏。

游戏命令

  1. play 默认命令,检查是否过关
  2. hint 提示
  3. reset 重置本关或到其他关
  4. levels 查看所有关卡

通过git levels发现一共有55关,真是任重而道远啊。

攻略

init

一个新的目录'git_hug'被创建成功,要求初始化该目录为一个仓库。

$ git init


config

设置自己在Git中的名字和Email,这十分重要,因为它们被用来标识你的提交。

$ git config user.name 'sonack'
$ git config user.email 'my_email@qq.com'

也可以加上"--global"参数来全局设定。


add

在你的目录中有一个叫做"README"的文件,你应该把它添加到你的暂存区(staging area)中,

$ git add README 


commit

"README"文件已经被加入你的暂存区中,现在提交(commit)它!

$ git commit -m 'add a README'


clone

克隆仓库 https://github.com/Gazler/cloneme

$ git clone https://github.com/Gazler/cloneme


clone_to_folder

克隆仓库 https://github.com/Gazler/cloneme 到 'my_cloned_repo'中。

$ git clone https://github.com/Gazler/cloneme my_cloned_repo


ignore

vim编辑器为所有当前打开的文件都生成了以".swp"结尾的交换文件,我们不希望它们污染我们的仓库,让这个仓库忽略".swp"文件。

$ echo "*.swp" >> .gitignore 

".gitignore"文件定义了忽略文件的规则。


include

注意到一些文件以".a"为后缀名,我们想要git忽略除了"lib.a"之外的所有".a"文件。

$ echo '!lib.a' >> .gitignore 
$ echo '*.a' >> .gitignore


status

仓库中有一些文件,其中之一没有被Git跟踪管理(untracked),找出它来!

$ git status

发现database.yml没有被跟踪。


number_of_files_committed

仓库中有一些文件,有多少文件会被提交(commit)呢?

$ git status 

发现有两个文件要被提交。


rm

一个文件已经从工作区中被删除了,但它还没有从仓库中删除,找到这个文件并彻底删除它!

$ git status
$ git add .
$ git commit -m '删除'

或者使用git rm .也可。


rm_cached

一个文件无意间被添加进了你的暂存区中,找出它并将它从暂存区中移出。

$ git rm --cached deleteme.rb 

因为是初始提交,所以使用git rm,否则一般使用git reset HEAD


stash

你已经做了一些更改,然后想以后再继续工作。你应该保存它们,但不要提交。

$ git stash


rename

我们有一个叫做"oldfile.txt"的文件,现在我们想要重命名它为"newfile.txt"并且存储这次改变。

$ git mv oldfile.txt newfile.txt

自动处于staged状态。


restructure

你在仓库中添加了几个文件,但是现在却意识到你的工程需要重新组织结构。创建一个新文件夹"src",并使用Git来移动所有".html"文件到"src"中。

$ mkdir src
$ git mv *.html src

使用git mv来重命名或者移动文件。


log

最近提交的hash值是多少?为此你可能需要查看log信息。

$ git log --pretty=format:"%h" -1


tag

我们现在有一个Git仓库,我们想给当前提交加上一个标签“new_tag”。

$ git tag new_tag

默认标签就是加在最新提交上的。


push_tags

当前分支有一些还没有推送到远程仓库的tags,现在推送它们。

$ git push origin --tags

一次性推送所有尚未推送的本地标签到远程仓库。


commit_amend

"README"文件已经被提交了,但是似乎"forgotten_file.rb"被忘记提交了。添加上这个文件,然后修正你的上一次提交,将它也提交进去。

$ git add forgotten_file.rb
$ git commit --amend


commit_in_future

以一个未来的日期来提交你的更改(比如,明天)。

$ git commit --date="2099-9-1"


reset

有两个文件要被提交,我们想单独提交它们,然而它们却意外地都被添加到了index中,利用reset命令先将文件"to_commit_second.rb"从index中撤出(注意不要commit)。

$ git reset HEAD to_commit_second.rb


reset_soft

你刚刚提交了不久,现在你想要撤销最后一次提交,但是保留index中的内容。

$ git reset --soft HEAD^


checkout_file

一个文件已经被修改了,但是你不想保留这次更改。将"config.rb"文件从上一次提交中checkout。

$ git checkout -- config.rb


remote

项目有一个远程仓库,找出它。

$ git remote

发现远程仓库的名字是"my_remote_repo"。


remote_url

远程仓库有其相关联的URL,请输入远程仓库"remote_location"的URL地址。

$ git remote -v

发现"remote_location"的URL是https://github.com/githug/not_a_repo


pull

你需要从origin远程仓库拉取更新。

$ git pull origin master


remote_add

添加一个叫作"origin"的远程仓库,URL地址是https://github.com/githug/githug

$ git remote add origin https://github.com/githug/githug


push

你的本地"master"分支和远程"origin/master"分支分叉了,在"origin/master"的基础上rebase你的commit,然后推送到远端。

$ git rebase origin/master
$ git push origin master

有关rebase的详细内容,请参阅博文<a href="">git rebase的用法</a>。


diff

自从你上次commit后,"app.rb"文件又被修改了,找出它的哪行被修改了。

$ git diff

发现第26行被修改了,关于git diff的格式如何理解,请参阅博文<a href="">git diff格式解析</a>


blame

某人在"config.rb"文件中放入了一个密码,找出来他是谁。

$ git blame -- config.rb

发现是Spider Man放入了密码i<3evil。

git blame会给出文件每行的commit SHA1,commiter,commit time and line number.
可以通过"-L"参数指定开始行和结束行,如

$ git blame -L 5,+2 F1.txt

会显示F1.txt的第5,6行

$ git blame -L 5,-2 F1.txt

会显示F1.txt的第4,5行

$ git blame -L n,m F1.txt

会显示F1.txt的第min(n,m)到第max(n,m)行(闭区间)。


branch

你想要做一些危险的代码编辑工作,创建一个叫"test_code"的分支。

$ git branch test_code


checkout

创建并切换到一个叫作"my_branch"的新分支,你可能会像上一关一样创建一个分支。

$ git checkout -b my_branch


checkout_tag

你需要在版本"v1.2"上修复一个BUG,切换到标签"v1.2"

$ git checkout v1.2


checkout_tag_over_branch

你需要在版本"v1.2"上修复一个BUG,切换到标签"v1.2"。(注意:还有一个叫作"v1.2"的分支)

$ git checkout tags/v1.2

使用"tags/v1.2"来指定切换到tag而不是branch。


branch_at

你在上一次提交之前,忘记创建分支了,直接提交在了本分支上。现在你要在上一次提交之前创建一个"test_branch"分支。

$ git branch test_branch HEAD^

即根据某个提交创建新分支


delete_branch

你创建了太多的分支,现在你的仓库中有一个叫作"delete_me"的老分支,你应该删除它。

$ git branch -d delete_me 


push_branch

你在本地仓库做了一些修改,希望与他人共享,但是并没有准备合并到master分支上。只推送给远程仓库"test_branch"这个分支。

$ git push origin test_branch

或者

$ git push origin test_branch:test_branch


merge

我们在"feature"分支中有一个文件,让我们把它合并到"master"分支上。

$  git merge feature 


fetch

看起来一个新分支已经被推送到我们的远程仓库中了,取得这些修改,不要把它们合并到本地仓库中。

$ git fetch origin

其实,git pull 就是 git fetchgit merge 的合体。


rebase

我们正在使用git freebase,"feature"分支已经准备好要合并进"master"分支中了,让我们rebase这个"feature"分支到"master"分支上。

$ git rebase master feature
$ git checkout master
$ git merge feature ## ff

git rebase --onto <newbase> --root [<branch>] ,有关git rebase的详细内容,请参阅博文<a href="">git rebase的用法</a>。


repack

优化你的仓库打包方式,以使得冗余的包裹(packs)被移除。

$ git repack -a -d


cherry-pick(择优选择)

你的新feature失败了,你想要删除它。但是它有一个commit,其中填充了"README"文件,你想要这个commit保留在"master"分支上。

$ git log --all  # 查看feature填充README的commit SHA为ca32...
$ git cherry-pick ca32

这样子,可以应用其他分支的某一个commit的修改到另外的分支上。


grep

你的项目deadline即将到来,你应该评估你的代码中还有多少TODOs了。

纯linux方法:

$ cat * | grep TODO | wc -l  # 得出有4个TODO

git grep方法:

$  git grep TODO | wc -l

在代码中根据正则表达式和条件进行搜索,功能十分强大。


rename_commit

更正你的第一个提交(非根提交)的提交信息中的错误。

$ git rebase -i 046edb

046edb是根提交的SHA1值。

修改为

reword 4e8470d First coommit
pick 72ef1a3 Second commit

然后再修改提交信息即可。

当涉及修改commit时,使用git rebase -i命令,它接受一个参数(commit SHA),它将罗列出此提交之后的所有提交,然后根据提示来对每个提交依次进行操作。


squash(压扁)

你提交了好几次,但是你想让它们都合并成一个提交。

$ git rebase -i e7757aff

修改为

pick 0559c6b Adding README
s 4c7e618 Updating README (squash this commit into Adding README)
s c0668f7 Updating README (squash this commit into Adding README)
s 9c4d834 Updating README (squash this commit into Adding README)

s(quash)表示使用该提交的修改,但和前一个提交融合。
然后输入新的提交信息即可。

或者使用f,和s相似,不同只是f直接丢弃被合并的commit的提交信息,直接使用Adding README。


merge_squash

合并所有"long-feature-branch"分支上的commit为一个单独的commit。

$ git merge --squash long-feature-branch
$ git commit -m 'merge long-feature-branch'

压缩提交,不会更新HEAD,将所有变更都放入"index"中。


reorder

你提交了几次,但是提交顺序错了。请更正你的提交的顺序。

$ git rebase -i 61d9af6c02b7df

调整顺序即可。


* bisect(二分debug)

在工作过程中,一个BUG产生了。你知道运行ruby prog.rb 5应该输出15,你也可以运行make test。请回答引入bug的commit的Hash值的前7位字符是什么?

$ git bisect start HEAD f608824
$ git bisect run make test

HEAD是当前有BUG的commit,f608824是"First commit",没有BUG的节点,在两者之间查找。

得到

18ed2ac1522a014412d4303ce7c8db39becab076 is the first bad commit

所以答案是"18ed2ac"。


stage_lines

你修改了一个同时属于两个不同"feature"的文件,但是它们都还没有被staged。请只Stage属于第一个"feature"的变化。

$ git add -p feature.rb 
diff --git a/feature.rb b/feature.rb
index 1a271e9..4a80dda 100644
--- a/feature.rb
+++ b/feature.rb
@@ -1 +1,3 @@
 this is the class of my feature
+This change belongs to the first feature
+This change belongs to the second feature
Stage this hunk [y,n,q,a,d,/,e,?]? 
$ e
# Manual hunk edit mode -- see bottom for a quick guide
@@ -1 +1,3 @@
this is the class of my feature
+This change belongs to the first feature
# ---
$ git diff
diff --git a/feature.rb b/feature.rb
index 3bccd0e..4a80dda 100644
--- a/feature.rb
+++ b/feature.rb
@@ -1,2 +1,3 @@
 this is the class of my feature
 This change belongs to the first feature
+This change belongs to the second feature

git diff的结果可以看到"feature1" 的修改已经被staged进index中了。

git add -p(--patch):交互式地选择调整由index到working tree的patch,然后把它们添加进index中。它给了用户在添加修改内容到index中时的一个复查审阅不同的机会。

使用git add --interactive命令也能选择patch操作,两者是等价的。


find_old_branch

你一直在某个分支上工作,但是中途被一次问题修复給搞乱了,忘记了之前分支的名字。请重回那个分支。

$ git reflog

发现之前从solve_world_hunger分支跳转到BUG修复分支。

$ git checkout solve_world_hunger

git reflog记录了每一次重要的ref发生变更时候的操作。


revert

你提交了若干次,但现在想撤销中间一次提交的操作。所有的commits都已经推送了,所以你不能更改已经存在的历史。

$ git revert d0aaaacf11dd19c54928

git revert只会撤销某一次commit的修改,并不影响其后的commit,因此可能会产生冲突,届时需要手工解决。


restore

你决定通过运行git reset --hard HEAD^命令来删除你的上一次提交(并不是个好方法),但是你突然改变了主意,想要让那个commit回来。请恢复被删除的commit。

$ git reflog
$ git reset --hard 14bd03f

通过git reflog找到之前commit的SHA,即可通过git reset恢复。


conflict

你需要合并"mybranch"分支到当前分支("master"分支)。但是在"mybranch"中似乎有一些可能会造成冲突的不正确的修改。解决你遇到的任何合并冲突,完成合并操作。

$ git merge mybranch
$ vim poem.txt
$ git add poem.txt
$ git commit -m '合并'

注意冲突文件的格式。

Humpty dumpty
<<<<<<< HEAD
Categorized shoes by color
=======
Sat on a wall
>>>>>>> mybranch
Humpty dumpty
Had a great fall

其中"<<<<<<< HEAD"到"======="之间的内容代表"HEAD"的修改,"======="到">>>>>>> mybranch"之间的内容代表"mybranch"的修改。手工修改,保留mybranch修改,删除HEAD修改,然后使用git add确认修改即可。


submodule

你想要包含仓库 https://github.com/jackmaney/githug-include-me 中的文件到一个"./githug-include-me"文件夹中。不要用克隆仓库的方式或者直接拷贝的方式来完成它。

$ git submodule add https://github.com/jackmaney/githug-include-me ./githug-include-me

submodule是一种很方便地将一个仓库分解为多个子模块的命令,特别是项目比较大且依赖于其他git项目时,比如cocos2d-x。


contribute

这是最后一关,目的是通过在Github上提起一个pull request来为这个项目仓库贡献源码。请注意,这一关只是为了鼓励你去为Githug项目做点贡献,并不是测试你去提起一个pull request的能力。可能被接受的贡献种类是关卡、BUG修复或者是文档完善。


至此,所有关卡已经完成。如果本文有什么错误或者问题,欢迎讨论!
如果你对git的基本知识还不熟悉,欢迎参考我的另一篇博文git笔记总结

参考资料:

  1. 「Githug」Git 游戏通关流程
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • git常用命令 GIT常用命令备忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章阅读 8,456评论 1 26
  • Git是目前最流行的版本管理系统,也是最先进的分布式版本控制系统(distributed version cont...
    pro648阅读 5,672评论 1 17
  • 一、整体分析 四月的3个核心目标: 寻找一套保持精力充沛的方法——完成按计划推进二分之一工程——完成读完《唤醒沉睡...
    演奏的船长阅读 282评论 3 3
  • 我问自己,你有“忙碌上瘾症”吗? 坦白说,有! 我有一个执念,人生短暂时间很宝贵,为了不浪费生命,我应该尽量多做一...
    萌妈育儿记阅读 525评论 11 9
  • 01 情景一:在公司楼下食堂吃完早餐,B1等电梯的时候,无意间听到两个看上去刚工作没几年女孩的聊天。A:最近腰好疼...
    雨林中的阳光阅读 461评论 0 11