GitHug通关手册

V2EX看到一个叫做githug的游戏,目的是让大家熟悉git,正好,我也是个只会add/commit/push的人(虽然自然不敢说精通)

安装(安装前请保证你安装了Ruby):

gem install githug

开玩。

第一关,init:

没有难度,git init

第二关,config:

需要设置username和email

git config --global user.name "SkyAo"
git config --global user.email foo@foo.com

第三关,add:

需要添加README到版本控制系统中。

git add README

第四关,commit:

需要commit我们添加完毕的README。

git commit README

第五关,clone:

克隆项目。

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

第五关,clone_to_dir:

这个看了一下help,需要克隆到指定目录:

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

第六关,.gitignore:

.gitignore自己一直不会写,所以搜了一下教程:http://segmentfault.com/a/1190000000522997

关于Example:

# 忽略所有 .a 结尾的文件
*.a

# 但 lib.a 除外
!lib.a

# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO

# 忽略 build/ 目录下的所有文件
build/

# 会忽略 doc/notes.txt 但不包括 doc/server/notes.txt
doc/notes.txt

实际上这个基本上已经是我们会遇到的情况集合了吧。

这里我们只要加上.swp即可。

第八关,include:

需要排除一个lib.a的文件,而把其他.a写进.gitignore。

上面已经有写了。

第九关,status:

在status中,我们可以看到哪些文件在版本控制下,那些文件没有。

git status

第十关,number_of_files_committed:

要统计多少文件被纳入版本控制下。

这个内心是崩溃的,他一直让我查看git status的内容,并且看了一下help,结果没看到什么东西。

后来只能去查一下stackoverflow,好好好:

git show --stat

这条会告诉你增加、修改、删除的文件变化量。下面这条则是配合Linux命令做到的(但是要-1)。

git whatchanged -1 --format=oneline | wc -l

第十一关,rm:

说的是虽然文件删除了,但在版本控制中仍然存在,我们需要找到这些文件并且删除它。

git status

里面有提示:

git rm deleteme.rb

就从版本控制中移除了。

第十二关,rm_cache:

不删除文件而从版本控制中删除。

git rm --cached deleteme.rb

这里如果我们执行git rm那么会提示:

(use --cached to keep the file, or -f to force removal)

说明git rm会有删除文件的效果,这和cache不同。

另外也告诉大家,使用rm对于版本控制而言并没有什么卵用。

第十三关,stash:

在这关中,我们假设需要在稍后使用这个分支,所以要保存更改(保存更改前切换分支将会丢失我的更新状态,如果你不提交分支的话)。

所以意味着,你还是需要git add的。

关于储藏,我们可以看这里:https://git-scm.com/book/zh/v1/Git-工具-储藏(Stashing)

不过我们这里只要运行一下

git stash

就行了。

第十四关,rename:

我们有一个文件名为oldfile.txt的文件,我们需要修改名字并且保存变更。

git mv oldfile.txt newfile.txt

如果你使用git status查看状态,会发现效果是:

renamed: oldfile.txt -> newfile.txt

而如果我们使用的是mv,则会产生删除了一个文件、添加了一个文件的效果。

第十五关,restructure:

创建一个src的文件夹并且将所有.html的文件移动至此目录。

git mv *.html src

查看git status

renamed:    about.html -> src/about.html

renamed: contact.html -> src/contact.html
renamed: index.html -> src/index.html

第十六关,log:

会问你最近提交的hash,用:

git log

关于git log,理所当然的也有话说:git log -1就能只显示最近一次了,具体还是看手册吧:https://git-scm.com/book/zh/v1/Git-基础-查看提交历史

第十七关,tag:

我们希望tag最近的提交为new_tag。

tag和分支类似,但其实是指向某commit的指针(或者说别名),然后就可以快速访问了。

需要添加tag:

git tag new_tag

当然,tag还有很多用法,比如说添加描述,签名,为指定commit打标签等:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001376951758572072ce1dc172b4178b910d31bc7521ee4000

第十八关,push_tags:

我们需要提交我们的tags。

git push --tags

上述网址的下一课讲的就是它。

第十九关,commit_amend:

有忘记commit的文件怎么办,我们现在就需要加入这个文件到该版本。(我经常遇到,但这种事情我从来不知道啊)

先用git add forgotten_file.rb添加,然后加上:

git commit --amend

关于此,我们可以在这里看到:https://backlogtool.com/git-guide/tw/stepup/stepup7_1.html

第二十关,commit_in_future:

需要给提交设定未来的某一个时间:

git commit --date='Sun Dec 31 22:09:11 2015 +0800'

第二十一关,reset:

两个文件需要单独提交但是结果两个文件一不小心一起提交了,我们需要还原一下to_commit_second.rb……

git reset HEAD to_commit_second.rb

然后我们会发现原来两个新文件中的一个脱离了版本控制。

第二十二关,reset_soft:

手太快,需要撤销提交,但索引要保留。

这题真是太拼了,提交了无数次:

git reset --soft HEAD@{1}

总算是在stackoverflow看到了新希望:http://stackoverflow.com/questions/5203535/practical-uses-of-git-reset-soft

第二十三关,checkout_file:

文件修改了,但我不希望add这个修改到这个版本的版本控制中,需要checkout这个文件。

git checkout config.rb

第二十四关,remote:

有一个远程仓库,我需要怎么知道它呢?

git remote

第二十五关,remote_url:

我现在需要知道远程仓库的地址。

git remote -v

或者:

git remote show remote_location

都能知道关于这个仓库的信息。

第二十六关,pull:

最常用的指令啦。

git pull origin master

第二十七关,remote_add:

我们需要添加一个叫做origin的remote仓库。

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

第二十八关,push:

接下俩我们需要提交到远程分支。

这里提示我们要rebase,也就是git rebase,关于rebase,可以看这里:http://gitbook.liuhui998.com/4_2.html

git rebase
git push

第二十九关,diff:

我们需要找出变更了几行代码。

git diff app.rb

第三十关,blame:

需要找出谁在程序中加了密码。

git blame可以查看每一行的作者

git blame config.rb

第三十一关,branch:

需要新建一个分支。

git branch test_code

第三十二关,checkout:

需要切换分支。

git checkout -b my_branch

这里相当于使用了

git branch my_branch
git checkout my_branch

branch的相关说明可以见:https://git-scm.com/book/zh/v1/Git-分支-分支的新建与合并

第三十三关,checkout_tag:

需要checkout一个tag。

这题刚开始不知道怎么回事,看了一下hint之后说:和branch并没有什么区别。

git checkout v1.2

第三十四关,checkout_tag_over_branch:

这里有同名的branch和tag,我需要的是checkout tag。

git checkout tags/v1.2

第三十五关,branch_at:

从指定的commit开新分支的意思。

git branch test_branch HEAD~1

详细介绍可以看:http://stackoverflow.com/questions/2816715/branch-from-a-previous-commit-using-git

第三十六关,delete_branch:

删除指定的分支。

git branch -d delete_me

第三十七关,push_branch:

只push指定的分支。

git push origin test_branch

第三十八关,merge:

两个branch需要merge一下。

git merge feature

第三十九关,fetch:

新的分支提交了,但我们只想获取,不想merge。

git fetch

第四十关,rebase:

同上面关卡的rebase的介绍。

git rebase master feature

这关万分不爽,去看了源代码才发现检查的是feature,rebase反了。

第四十一关,repack:

repack差不多就是消除冗余,进一步优化的意思了。

git repack -d

……这里不知道。

第四十二关,cherry-pick:

我们想要删除分支,在删除分支之前,需要移动一些commit到主分支。

git log new-feature查看一下对应的commit id:

git cherry-pick ca32a6dac7b6f97975edbe19a4296c2ee7682f68

在主分支下进行操作,cherry-pick的详细资料:http://backlogtool.com/git-guide/cn/stepup/stepup7_4.html

第四十三关,grep:

我想知道还剩下多少todo。

git grep TODO

git grep可以很方便的在版本库中搜索指定文字:http://gitbook.liuhui998.com/4_8.html

第四十四关,rename_commit:

因为在过去的commit中有错字需要修正。

首先我们看了一下help,然后发现似乎并没有什么,看log,找到commit id。

git rebase -i 9d101f50a24e7b7a30f015041a19149e061ce588

退回到需要修改的上一个,他会告诉你删除的话表示舍弃这个commit,reword是修改,所以我们把pick改成reword。

第四十五关,squash:

我提交了几次不过似乎这几个提交应该变成一个提交。(也是我经常犯的坑)。

命令行语句一样,不同的是我们这次不用reword而使用squash将下面的合并。

第四十六关,merge_squash:

我们需要将另一分支下的commit合并后并入主分支。

当然不是直接移入,需要在运行完指令后再做commit操作。

git merge --squash long-feature-branch

第四十七关,reorder:

差不多意思是,虽然我提交了,但是提交的顺序错了,要把它在排序一下。

他依旧提示我使用git rebase -i,嗯照旧。

这次我们需要交换两个,其实更简单,交换两行的顺序就行了,vim中,可以使用ddp快速实现。

第四十八关,bisect:

bisect是两分查找根据版本号排错,关于怎么使用,在这里可以看到:https://git-scm.com/book/zh-tw/v1/Git-工具-使用-Git-做-Debug

首先我们需要:

git bisect start

接下来我们要告诉机器,我们最近一次已知正确是在什么版本。

git bisect good [good_commit]

接下来调试bad,接下来就可以用git bisect good/git bisect bad加上运行调试进行测试了。

测试到不对的情况,那么记录其commit_id

第四十九关,stage_lines:

这里说的是,虽然我们更新了一个文件,但他的两行不应该在同一个情况里被添加上去的情况该怎么办。

git add -p

再按一次回车会出现提示,根据提示我们edit。

第五十关,find_old_branch:

这里说的是虽然我们切换到了新分支但忘了旧分支的名字,要找回旧的分支。

git reflog

可以查看我们的操作情况。

第五十一关,revert:

虽然你提交了很多次不过需要撤销中间的一次,这次中,我们已经提交上去了,所以不能修改已存在的历史。

在这里我们也有告诉你怎么还原:http://gitbook.liuhui998.com/4_9.html

我们可以看到bad的是第二条。

git revert HEAD^

第五十二关,restore:

虽然已经git reset --hard HEAD^了,但我还想抢救一下。

git reflog

查看一下位置,发现完毕:

git reset --hard HEAD@{1}

恢复这个文件。

第五十三关,conflict:

这个关卡讲的是要人工merge的情况。

git merge mybranch

注意,我们首先不能有merge的标记,其次,Sat on a wall应该在文件中。

git add .
git commit -m "confict"

第五十四关,submodule:

这也是我的需求之一,就是想在git里放独立的git仓库怎么办。

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

这样就会保证他们的相对独立:https://git-scm.com/book/zh/v1/Git-工具-子模块

第五十五关,contribute:

至今算是全部结束啦,最后一关是希望你能给这个项目做出一些贡献。

如果您觉得文章不错,可以通过赞助支持我

标签: 命令, 使用, git

已有 4 条评论

  1. 硫酸

    NO.41 repack
    错了 应该是 git repack -d
    (其实我也不知道 +1

    1. 嗯谢谢管哥提醒!确实忘记改了!

  2. 很好的文章,请问可以转载收藏吗?

    1. 可以的 注明出处就行

添加新评论