「Githug」Git 游戏通关流程

jopen 8年前

Githug

他喵的这是个啥!?难道不是 GitHub 拼错了么,和 Git 什么关系? 和游戏又有什么关系?

其实,他的元身在这里:https://github.com/Gazler/githug ,这个命令行工具被设计来练习你的 Git 技能,它把平常可能遇到的一些场景都实例化,变成一个一个的关卡,一共有 55 个关卡,所以将他形象的形容为 Git 游戏。

既然是游戏,作为一个专业的游戏玩家,通关自然是我的最终目标了!!!

安装游戏

没什么好说的,终端运行如下命令即可,如果碰到了墙,自行搬梯子


安装游戏(盗个图)
</div>

游戏开始

直接输入 githug 就可以开始游戏了!开始的时候会询问是否创建文件夹,输入 y 确认创建,以后的操作将都在这个文件夹中进行。


游戏开始
</div>

第一关(Init)

紧接着,马上进入到了第一个关卡, 按照提示初始化这个这个 githug 文件夹为仓库。完成关卡可以通过调用 githug play 验证操作,成功则会进入下一个关卡


第一关
</div>

第二关(Config)

设置 Git 用户名和邮箱,为了不影响全局的配置,我设置的是仓库级别的。


第二关
</div>

第三关 (Add)

使用 add 命令将 README 文件添加到 staging area.


第三关
</div>

第四关 (Commit)

提交 README 文件,记得每次 commit 使用 -m 参数加上备注是个好习惯


Paste_Image.png
</div>

第五关(Clone)

克隆一个仓库,默认的文件夹名是远端的仓库名


第五关
</div>

第六关(Clone to folder)

同样是克隆一个仓库,不同的是可以指定一个文件夹名


第六关
</div>

第七关(Ignore)

忽略所有 .swp 后缀名的文件。这里使用 vim 编辑器打开 .gitignore,这个文件记录了 git 忽略文件的规则, 不会 vim 的同学可以用自己熟悉的编辑器。


第七关
</div>

使用正则(glob 模式)匹配所有的 .swp 文件,然后保存并退出


操作 .gitignore 文件
</div>

第八关(Include)

除了 lib.a 文件,其他所有的 .a 后缀名的文件都忽略。和上一关的操作一样,修改 .gitignore 文件


第八关
</div>

其中 # 开头的是注释,用 *.a 匹配所有 .a 文件,! 开头代表不要忽略


操作 .gitignore 文件
</div>

第九关(Status)

查看所有处于 untracked 状态的文件。使用 git status 查看当前仓库的状态,可以看到红色部分就是 untracked 状态的文件


第九关
</div>

第十关(Number of files committed)

其实就是查看处于 staged 状态的文件,图中黄色部分就是,所以个数就是2


第十关
</div>

第十一关(rm)

有一个文件从硬盘中删除了,但是并未从 git 仓库中删除,找到它并从 git 仓库中删除。删除也是修改的一种,提交这个修改就好了


第十一关
</div>

第十二关(rm cached)

讲一个新文件从 staging area 中删除。按照要求,不应该直接从硬盘上删除这个文件,只是从 Git 中删除而已。加上 --cache 可以是文件只是从 staging area 中移除,不会真正的删除物理文件,如果要连这个物理文件也一起删除,请使用 -f 选项


第十二关
</div>

第十三关(stash)

临时提交某个文件。这个操作在需要临时保存修改,而又不想提交的时候特别好用!而且 git 中维护了一个栈来保存,所以支持提交多次。如果需要恢复某次提交,使用 git stash apply 即可。


第十三关
</div>

第十四关(Rename)

重命名文件。首先这个文件需要是已经是已追踪状态,才可以使用 git mv 命令,操作完成后自动处于 staging 状态


重命名文件
</div>

第十五关(Restructure)

移动所有 .html 文件到 src 文件夹。git mv 后面的第二个参数可以接受文件或目录,如果是目录,则文件会直接放入目录内,可以使用正则(glob模式)匹配所有 .html 文件


第十五关
</div>

第十六关(Log)

找到最新的 commit 的 hash 值。使用 git log 查看历史提交记录, 找到最新的 commit 的 hash 值,记录下来用户回答问题


回答问题
</div>

这里是按照倒叙排列的,最新的在最前面,commit 关键字后面跟着的就是这个 commit 的 hash 值


查看历史记录
</div>

第十七关(Tag)

为最新的 commit 打 tag。不加额外参数就是为当前 commit 记录 tag, 当然可以为特定的 commit 打


Paste_Image.png
</div>

第十八关(Push tags)

将所有本地 tag 都推送到远端。--tags 参数代表将所有的 tags 都推送到远端


第十八关
</div>

第十九关(Commit amend)

某个文件在上次提交中遗漏了,在那次提交中补上这个文件。 其实,使用 git commit --amend 会进入编辑界面修改备注信息,我这里直接 :wq 保存并退出


第十九关
</div>

第二十关(Commit in feature)

为提交指定一个未来的时间。


第二十关
</div>

备注操作界面
</div>

第二十一关(Reset)

两个文件都被添加到了 staging area, 但是只想提交其中一个。使用 git reset 可以用仓库中的版本覆盖 staging area 的版本。

  • git reset 使用仓库中的版本覆盖 staging area 中的,如果 working directory 该文件没有其他修改,则 staging area 中的修改将应用到 working directory 中。反之working directory 中的版本将被保留,丢弃 staging area 中的修改。
  • git checkout 则是使用 staging area 的中的版本覆盖 working directory

    Paste_Image.png

第二十二关(Reset soft)

撤销上一次提交。

  • --soft 参数将上一次的修改放入 staging area
  • --mixed 参数将上一次的修改放入 working directory
  • --hard 参数直接将上一次的修改抛弃

    第二十二关

第二十三关(Checkout file)

抛弃某一次的修改,使用上次提交的版本。checkoutreset 的区别参照第二十一关


第二十三关
</div>

第二十四关(Remote)

查看远端仓库。其实可以不加-v参数,加这个参数只是可以将地址也一起输出(没想到下一关就是考察这个参数,平常习惯加这个参数了。。。)


第二十四关
</div>

第二十五关(remote url)

查看远端仓库的 URL


第二十五关
</div>

第二十六关(pull)

拉取远端仓库。
其实可以指定分支,格式如下

git pull origin remote : local

对应的推送的格式如下

git push origin local : remote

需要注意的两个操作的分支顺序是相反的,记忆的方法很简单,拉取是从远端到本地,所以远端在前,而推送是从本地到远端,所以本地在前。


第二十六关
</div>

第二十七关(Remote add)

添加一个远端仓库


第二十七关
</div>

第二十八关(Push)

推送本地修改到远端


Paste_Image.png
</div>

第二十九关(Diff)

查看 staging areaworking directory 中文件的差异。


第二十九关
</div>

对应 git diff 的显示结果


差异信息
</div>

第三十关(Blame)

查看某个文件的修改人。这个命令简直邪恶,锅终于有人背了!!!


第三十关
</div>

git blame 列出了文件中每行的修改人是谁


文件修改记录
</div>

第三十一关(Branch)

创建一个分支


第三十一关
</div>

第三十二关(Checkout)

创建一个分支,并切换过去。其实,git checkout -b my_branch 就是创建一个分支,并切换过去,而且这种方法更方便,平常用的更多


Paste_Image.png
</div>

第三十三关(Checkout tag)

切换到某个特定的 tag


第三十三关
</div>

第三十四关(Checkout tag over branch)

切换到某个特定的分支,但是分支名和标签名重叠了


第三十四关
</div>

第三十五关(branch at)

根据一个特定的提交创建新分支


第三十五关
</div>

第三十六关(delete branch)

删除一个分支


第三十六关
</div>

第三十七关(Push branch)

将分支推送到远端仓库


Paste_Image.png
</div>

第三十八关(merge)

合并分支。为了简化分支模型,可以使用 rebase 代替,后续关卡会遇到。


第三十八关
</div>

第三十九关(fetch)

获取远端的修改,但是并不合并到当前分支。其实,git pull 就是 git fetchgit merge 组成的。


第三十九关
</div>

第四十关(rebase)

其实不知道怎么翻译 git rebase 这个命令。大概意思是从某个提交分化出两个分支,然后其中一个分支需要将另一个分支的修改合并过来,但是又不想在提交记录上留下两个分支合并的痕迹,只留下一个分支以前后顺序记录两边的修改。

git rebase 一个分支的所有修改在另一个分支上重新应用一遍,所以在提交记录上看,会发现一个分支的所有提交在另一个分支之前或者之后。然后删除另一个被合并的分支,保持分支简洁。

git rebase master feature 表示将 feature 上的修改在 master 上重新应用一遍


第四十关
</div>

对应第一个 git log --graph -all--graph会用图形化将提交记录显示出来,而--all 会显示所有分支的提交记录


原始状态
</div>

对应第而二个 git log --graph -all ,可以发现只保留了一个分支,看起来简洁了很多。


Paste_Image.png
</div>

在使用此命令的时候,需要非常注意的是,不要 rebase 哪些已经推送到公共库的更新,因为此操作是重新应用修改,所以公共库的更新可能已经被其他协作者所同步,如果再次 rebase 这些修改,将可能zh

第四十一关(repack)

将版本库未打包的松散对象打包


第四十一关
</div>

第四十二关(cherry pick)

应用某一个提交的修改。


第四十二关
</div>

找到我们想要的那个提交,记录下它的 hash 值
ca32a6dac7b6f97975edbe19a4296c2ee7682f68


Paste_Image.png
</div>

第四十三关 (Grep)

git grep支持各种条件搜索及正则表达式,平时用的不多,但感觉功能强大。


第四十三关
</div>

对应 git grep TODO 的结果


搜索结果
</div>

第四十四关(rename commit)

重命名提交。当涉及提交修改时,应该想到 git rebase -i 命令,它接受可以一个参数(提交的哈希值),它将罗列出此提交之后的所有提交,然后可以对个个提交做对应的操作。


第四十四关
</div>

重命名前的提交记录


重命名前
</div>

将需要重命名的提交前的 pick 修改为 reword


选择需要重命名的提交
</div>

修改成新的备注,保存并推出


Paste_Image.png
</div>

第四十五关(squash)

合并多个提交。


第四十五关
</div>

合并前的提交记录。


Paste_Image.png
</div>

将需要合并的提交前的 pick 改成 squashssquash 代表并入前一个提交,保存并退出。


Paste_Image.png
</div>

为新的提交修改备注


Paste_Image.png
</div>

第四十六关(merge squash)

将某个分支上的所有修改都应用成一个提交。默认修改都将进入暂存区


Paste_Image.png
</div>

第四十七关

重新排列提交顺序。


第四十七关
</div>

排序前,对应第一个 git log


Paste_Image.png
</div>

在编辑界面,将 Second commitThird commit 的顺序调换


Paste_Image.png
</div>

排序后,对应第二个 git log


Paste_Image.png
</div>

第四十八关

使用 git log 查看所有的提交记录,太长我就不全贴出来了,找到最开始的提交 f608824888b83bbedc1f658be7496ffea467a8fb


Paste_Image.png
</div>

git bisect start master f608824888b83 中,master 是有 bug 的节点,f608824888b83 是没有 bug 的节点。


Paste_Image.png
</div>

第四十九关(Stage lines)

其实,提交文件的部分修改这种需求平时还是比较常见的,不过平时都是用 Source Tree 来操作的,但是看到这题之后,好像又开启了一扇大门。


Paste_Image.png
</div>

Paste_Image.png
</div>

Paste_Image.png
</div>

第五十关(Find old branch)

git reflog 可以列出所有的操作记录,所以找到之前忘记的信息并不是什么难事


第五十关
</div>

对应 git reflog 的显示内容


Paste_Image.png
</div>

第五十一关(Revert)

reset 不同的是,revert 只会撤销当前的 commit,而之后的 commit 操作的修改还会保留,但是reset 还会将之后的所有 commit 操作的修改全部退回 staging area 或丢弃。


第五十一关
</div>

这是执行撤销操作前的记录,对应第一个git log


撤销前的记录
</div>

撤销操作会生成一个新的 commit,保存并退出即可


新的 commit
</div>

撤销之后的记录,它不破坏原有的记录,对应第二个 git log


撤销后的记录
</div>

第五十二关(Restore)

根据之前的经验,git reflog 可以查看所有的操作记录,所以只要能找到误操作之前的 commit id,一样能够恢复现场。


第五十二关
</div>

执行 git reflog 后画面如下,根据操作记录,找到你误操作的之前的 commit id


操作记录
</div>

第五十三关(Conflict)

冲突处理在平常的协同工作中真是再常见不过了,需要注意的是存在冲突的文件是在 working directory 中的,在解决完冲突之后需要添加到 staging area 并提交。


第五十三关
</div>

其实冲突解决完成的图片丢失了,只能口述了。
<<<<<<< HEAD======= 之间的内容代表 master 分支的修改,=======>>>>>> mybranch 之间的内容代表 mybranch 分支的修改,保留 mybranch 分支的修改,删除master 分支的修改即可,当然这些特殊符号所在行也要一并删除。


处理冲突
</div>

第五十四关(Submodule)

submodule 是一个很方便的将一个仓库分解成多个子模块的命令,特别是项目比较大且依赖其他 Git 项目的时候,比如 Cocos2d-x。虽然好用,但是门槛也相对高点,如果维护好 submodule 还是需要好好研究一下。


第五十四关
</div>

第五十五关(Contribute)

其实到这里已经可以算是通关,如果感兴趣的话可以到 GitHub 为这个项目贡献代码。


第五十五关
</div>

结尾

其实这里的所有关卡展示的内容只是 Git 的冰山一角,Git 的魅力远不止这些,还需我们慢慢探索~

如果文章有表述错误,欢迎指正。

最后,感谢这篇文章带我入坑:
http://gold.xitu.io/entry/5684844560b2cd25b7cb41a3

来自: http://www.jianshu.com/p/482b32716bbe