githug是一个让你熟悉git命令的小游戏,项目地址在这里https://github.com/Gazler/githug 。看了一下commit记录发现是几年前就有这个了,只是前些天我的rss几个源都推荐了,恰好又在v2ex上看到,就试玩了一下。
  我之前一直是使用SourceTree这个GUI软件来使用git,这个软件真的很好用。我就借此机会通过githug来强化一下对git命令的使用,顺便把我的攻略粘在这里以供参考。大部分是我自己写的,有些黑魔法和一些没见过的指令是我在网上查的,比如41,和44往后99%的内容:p。

  githug的安装和使用在项目主页里都有,我就不多说了。


Level1: init

A new directory, git_hug, has been created; initialize an empty repository in it.

git仓库初始化

1
2
cd git_hug/
git init


Level2: config

Set up your git name and email, this is important so that your commits can be identified.

设置你使用git的名字和邮箱地址

1
2
git config --global user.name altair21
git config --global user.email lovealtair21@gmail.com


Level3: add

There is a file in your folder called README, you should add it to your staging area
Note: You start each level with a new repo. Don’t look for files from the previous one.

add命令的使用

1
git add README


Level4: commit

The README file has been added to your staging area, now commit it.

commit命令的使用

1
git commit -m "add README"


Level5: clone

Clone the repository at https://github.com/Gazler/cloneme.

clone命令的使用

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


Level6: clone_to_folder

Clone the repository at https://github.com/Gazler/cloneme to my_cloned_repo

clone命令不加任何参数是clone到当前目录,现在clone到指定目录

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


Level7: ignore

The text editor ‘vim’ creates files ending in .swp (swap files) for all files that are currently open. We don’t want them creeping into the repository. Make this repository ignore .swp files.

.gitignore文件的使用,忽略后缀为swp的文件
在.gitignore文件中添加一行:

1
*.swp


Level8: include

Notice a few files with the ‘.a’ extension. We want git to ignore all but the ‘lib.a’ file.

还是.gitignore文件的使用,忽略后缀为a的文件,但是不忽略lib.a文件
在.gitignore文件中添加:

1
2
*.a
!lib.a

取反符号在这里会起作用


Level9: status

There are some files in this repository, one of the files is untracked, which file is it?

status命令的使用

1
git status

结果如图:

Untracked files一目了然


Level10: number_of_files_committed

There are some files in this repository, how many of the files will be committed?

同样是status命令

1
git status

输入文件个数就行了


Level11: rm

A file has been removed from the working tree, however the file was not removed from the repository. Find out what this file was and remove it.

先找到被删除的文件,再从仓库中删除

1
2
git status
git rm deleteme.rb


Level12: rm_cached

A file has accidentally been added to your staging area, find out which file and remove it from the staging area. NOTE Do not remove the file from the file system, only from git.

先找到在暂存区的文件,在从暂存区移除

1
2
git status
git rm --cached deleteme.rb


Level13: stash

You’ve made some changes and want to work on them later. You should save them, but don’t commit them.

stash命令的使用

1
git stash


Level14: rename

We have a file called oldfile.txt. We want to rename it to newfile.txt and stage this change.

修改文件命并且添加到暂存区

1
git mv oldfile.txt newfile.txt


Level15: restructure

You added some files to your repository, but now realize that your project needs to be restructured. Make a new folder named src and using Git move all of the .html files into this folder.

还是git mv

1
2
mkdir src
git mv *.html src


Level16: log

You will be asked for the hash of most recent commit. You will need to investigate the logs of the repository for this.

log命令的使用,找到最新一发commit的哈希值

1
git log -1


Level17: tag

We have a git repo and we want to tag the current commit with new_tag.

tag命令的使用

1
git tag new_tag


Level18: push_tags

There are tags in the repository that aren’t pushed into remote repository. Push them now.

push标签

1
git push origin --tags


Level19: commit_amend

The README file has been committed, but it looks like the file forgotten_file.rb was missing from the commit. Add the file and amend your previous commit to include it.

追加commit

1
2
git add forgotten_file.rb
git commit --amend -m "aaa"


Level20: commit_in_future

Commit your changes with the future date (e.g. tomorrow).

自定义commit时间

1
git commit --date=2016.01.10 -m "commit"


Level21: reset

There are two files to be committed. The goal was to add each file as a separate commit, however both were added by accident. Unstage the file to_commit_second.rb using the reset command (don’t commit anything).

unstage操作

1
git reset HEAD to_commit_second.rb


Level22: reset_soft

You committed too soon. Now you want to undo the last commit, while keeping the index.

版本回退并且修改保留到暂存区

1
git reset --soft HEAD~1


Level23: checkout_file

A file has been modified, but you don’t want to keep the modification. Checkout the config.rb file from the last commit.

丢弃修改

1
git checkout config.rb


Level24: remote

This project has a remote repository. Identify it.

remote命令的使用

1
git remote


Level25: remote_url

The remote repositories have a url associated to them. Please enter the url of remote_location.

还是remote命令的使用

1
git remote -v


Level26: pull

You need to pull changes from your origin repository.

pull命令的使用

1
git pull origin master


Level27: remote_add

Add a remote repository called origin with the url https://github.com/githug/githug

添加远程仓库

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


Level28: push

Your local master branch has diverged from the remote origin/master branch. Rebase your commit onto origin/master and push it to remote.

rebase命令的使用
这个命令没用过,网上找的答案

1
2
git rebase origin/master
git push origin master


Level29: diff

There have been modifications to the app.rb file since your last commit. Find out which line has changed.

diff命令的使用

1
git diff

如下图所示:

蓝色的那行格式是@@ -start,count +start,count @@,红色表示被删除,绿色表示新增,所以变化的行号是26


Level30: blame

Someone has put a password inside the file config.rb find out who it was.

blame命令的使用
找到密码对应行的提交者

1
git blame config.rb


Level31: branch

You want to work on a piece of code that has the potential to break things, create the branch test_code.

创建branch

1
git branch test_code


Level32: checkout

Create and switch to a new branch called my_branch. You will need to create a branch like you did in the previous level.

checkout命令的使用,创建branch并切换到这个branch

1
git checkout -b my_branch


Level33: checkout_tag

You need to fix a bug in the version 1.2 of your app. Checkout the tag v1.2.

还是checkout命令的使用

1
git checkout v1.2


Level34: checkout_tag_over_branch

You need to fix a bug in the version 1.2 of your app. Checkout the tag v1.2 (Note: There is also a branch named v1.2).

上面的命令中的v1.2是标签名,在没有同名的分支时可以这么用,现在有个同名的分支也叫v1.2,上面的命令默认是切换到v1.2分支,如果要切换到标签就要用下面的命令了:

1
git checkout tags/v1.2


Level35: branch_at

You forgot to branch at the previous commit and made a commit on top of it. Create branch test_branch at the commit before the last.

把上一发commit添加到新的分支,这个是网上查的

1
git branch test_branch HEAD~1


Level36: delete_branch

You have created too many branches for your project. There is an old branch in your repo called ‘delete_me’, you should delete it.

删除branch

1
git branch -d delete_me


Level37: push_branch

You’ve made some changes to a local branch and want to share it, but aren’t yet ready to merge it with the ‘master’ branch. Push only ‘test_branch’ to the remote repository

push branch

1
git push origin test_branch


Level38: merge

We have a file in the branch ‘feature’; Let’s merge it to the master branch.

merge命令的使用

1
git merge feature


Level39: fetch

Looks like a new branch was pushed into our remote repository. Get the changes without merging them with the local repository

fetch命令的使用

1
git fetch origin


Level40: rebase

We are using a git rebase workflow and the feature branch is ready to go into master. Let’s rebase the feature branch onto our master branch.

rebase命令的使用

1
2
git checkout feature
git rebase master


Level41: repack

Optimise how your repository is packaged ensuring that redundant packs are removed.

这个命令压根没见过,help里的说明如图


1
git repack -d


Level42: cherry-pick

Your new feature isn’t worth the time and you’re going to delete it. But it has one commit that fills in README file, and you want this commit to be on the master as well.

cherry-pick命令的使用,找到对应的commit id

1
git log --pretty=format:'%h - %d %s : %cr <%an - %ae>' --graph --branches

log信息如下图所示:

根据commit信息找到对应的hash,然后再执行cherry-pick

1
git cherry-pick ca32a6dac7b6f97975edbe19a4296c2ee7682f68

关于log format的占位符说明,可以参照这里


Level43: grep

Your project’s deadline approaches, you should evaluate how many TODOs are left in your code

找到”TODO”字符串的个数

1
git grep -c TODO


Level44: rename_commit

Correct the typo in the message of your first (non-root) commit.

修改commit信息

1
2
git log
git rebase -i 601fa90

将vim打开的文件中First coommit前的pick改为reword,保存退出,自动打开新的文件,修改commit信息


Level45: squash

You have committed several times but would like all those changes to be one commit.

合并几个commit为一个

1
2
git log
git rebase -i 618a846

进入vim将commit前的pick改为s,留着第一发commit不改


Level46: merge_squash

合并分支并提交commit

1
2
git merge --squash long-feature-branch
git commit -m "commit"


Level47: reorder

You have committed several times but in the wrong order. Please reorder your commits.

改变commit顺序

1
2
git log
git rebase -i 89afdd

进入vim将第二行和第三行互换位置


Level48: bisect

A bug was introduced somewhere along the way. You know that running ruby prog.rb 5 should output 15. You can also run make test. What are the first 7 chars of the hash of the commit that introduced the bug.

用二分法找到结果值和预期值第一次不同是在哪一发commit
先将头尾commit分别设置为good和bad,二分找的时候对每一个middle值手动判断good/bad,最后定位到第一次bad的位置

1
2
3
4
git bisect start
git bisect good f608824
git bisect bad master
ruby prog.rb 5 #看结果是否为15,标记good/bad,如此反复


Level49: stage_lines

You’ve made changes within a single file that belong to two different features, but neither of the changes are yet staged. Stage only the changes belonging to the first feature.

只将文件中的某些行添加到暂存区

1
git add feature.rb -e

删掉不想添加的行,保存。(这种操作在SourceTree里方便)


Level50: find_old_branch

You have been working on a branch but got distracted by a major issue and forgot the name of it. Switch back to that branch.

reflog(reference log的缩写)命令的使用,找出之前所在的分支

1
2
git reflog
git checkout solve_world_hunger


Level51: revert

You have committed several times but want to undo the middle commit.
All commits have been pushed, so you can’t change existing history.

revert命令的使用

1
2
git log
git revert 01719e9


Level52: restore

You decided to delete your latest commit by running git reset --hard HEAD^. (Not a smart thing to do.) You then change your mind, and want that commit back. Restore the deleted commit.

reflog命令的使用,找回被删除的commit(被坑过,全是泪)

1
2
git reflog
git checkout 3e84a7e


Level53: conflict

You need to merge mybranch into the current branch (master). But there may be some incorrect changes in mybranch which may cause conflicts. Solve any merge-conflicts you come across and finish the merge.

修复合并后的冲突,刚实习的时候也被这个坑过

1
2
3
git merge mybranch
git mergetool
git commit -m "merged"


Level54: submodule

You want to include the files from the following repo: https://github.com/jackmaney/githug-include-me into a the folder ./githug-include-me. Do this without cloning the repo or copying the files from the repo into this repo.

submodule命令的使用

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


Level55: contribute

This is the final level, the goal is to contribute to this repository by making a pull request on Github. Please note that this level is designed to encourage you to add a valid contribution to Githug, not testing your ability to create a pull request. Contributions that are likely to be accepted are levels, bug fixes and improved documentation.