Githug
他喵的這是個啥!?難道不是 GitHub 拼錯了么,和 Git 什么關系? 和游戲又有什么關系?
其實,他的元身在這里:https://github.com/Gazler/githug ,這個命令行工具被設計來練習你的 Git 技能,它把平常可能遇到的一些場景都實例化,變成一個一個的關卡,一共有 55 個關卡,所以將他形象的形容為 Git 游戲。
既然是游戲,作為一個專業的游戲玩家,通關自然是我的最終目標了!!!
安裝游戲
沒什么好說的,終端運行如下命令即可,如果碰到了墻,自行搬梯子
游戲開始
直接輸入 githug
就可以開始游戲了!開始的時候會詢問是否創建文件夾,輸入 y
確認創建,以后的操作將都在這個文件夾中進行。
第一關(Init)
緊接著,馬上進入到了第一個關卡, 按照提示初始化這個這個 githug
文件夾為倉庫。完成關卡可以通過調用 githug play
驗證操作,成功則會進入下一個關卡
第二關(Config)
設置 Git 用戶名和郵箱,為了不影響全局的配置,我設置的是倉庫級別的。
第三關 (Add)
使用 add
命令將 README 文件添加到 staging area.
第四關 (Commit)
提交 README 文件,記得每次 commit
使用 -m
參數加上備注是個好習慣
第五關(Clone)
克隆一個倉庫,默認的文件夾名是遠端的倉庫名
第六關(Clone to folder)
同樣是克隆一個倉庫,不同的是可以指定一個文件夾名
第七關(Ignore)
忽略所有 .swp
后綴名的文件。這里使用 vim 編輯器打開 .gitignore
,這個文件記錄了 git 忽略文件的規則, 不會 vim 的同學可以用自己熟悉的編輯器。
使用正則(glob 模式)匹配所有的 .swp
文件,然后保存并退出
第八關(Include)
除了 lib.a
文件,其他所有的 .a
后綴名的文件都忽略。和上一關的操作一樣,修改 .gitignore
文件
其中 #
開頭的是注釋,用 *.a
匹配所有 .a
文件,!
開頭代表不要忽略
第九關(Status)
查看所有處于 untracked
狀態的文件。使用 git status
查看當前倉庫的狀態,可以看到紅色部分就是 untracked
狀態的文件
第十關(Number of files committed)
其實就是查看處于 staged 狀態的文件,圖中黃色部分就是,所以個數就是2
第十一關(rm)
有一個文件從硬盤中刪除了,但是并未從 git 倉庫中刪除,找到它并從 git 倉庫中刪除。刪除也是修改的一種,提交這個修改就好了
第十二關(rm cached)
講一個新文件從 staging area
中刪除。按照要求,不應該直接從硬盤上刪除這個文件,只是從 Git 中刪除而已。加上 --cache
可以是文件只是從 staging area
中移除,不會真正的刪除物理文件,如果要連這個物理文件也一起刪除,請使用 -f
選項
第十三關(stash)
臨時提交某個文件。這個操作在需要臨時保存修改,而又不想提交的時候特別好用!而且 git 中維護了一個棧來保存,所以支持提交多次。如果需要恢復某次提交,使用 git stash apply
即可。
第十四關(Rename)
重命名文件。首先這個文件需要是已經是已追蹤狀態,才可以使用 git mv
命令,操作完成后自動處于 staging 狀態
第十五關(Restructure)
移動所有 .html
文件到 src
文件夾。git mv
后面的第二個參數可以接受文件或目錄,如果是目錄,則文件會直接放入目錄內,可以使用正則(glob模式)匹配所有 .html 文件
第十六關(Log)
找到最新的 commit 的 hash 值。使用 git log
查看歷史提交記錄, 找到最新的 commit 的 hash 值,記錄下來用戶回答問題
這里是按照倒敘排列的,最新的在最前面,commit
關鍵字后面跟著的就是這個 commit 的 hash 值
第十七關(Tag)
為最新的 commit 打 tag。不加額外參數就是為當前 commit 記錄 tag, 當然可以為特定的 commit 打
第十八關(Push tags)
將所有本地 tag 都推送到遠端。--tags
參數代表將所有的 tags 都推送到遠端
第十九關(Commit amend)
某個文件在上次提交中遺漏了,在那次提交中補上這個文件。 其實,使用 git commit --amend
會進入編輯界面修改備注信息,我這里直接 :wq
保存并退出
第二十關(Commit in feature)
為提交指定一個未來的時間。
第二十一關(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)
拋棄某一次的修改,使用上次提交的版本。checkout
和 reset
的區別參照第二十一關
第二十四關(Remote)
查看遠端倉庫。其實可以不加-v
參數,加這個參數只是可以將地址也一起輸出(沒想到下一關就是考察這個參數,平常習慣加這個參數了。。。)
第二十五關(remote url)
查看遠端倉庫的 URL
第二十六關(pull)
拉取遠端倉庫。
其實可以指定分支,格式如下
git pull origin remote : local
對應的推送的格式如下
git push origin local : remote
需要注意的兩個操作的分支順序是相反的,記憶的方法很簡單,拉取是從遠端到本地,所以遠端在前,而推送是從本地到遠端,所以本地在前。
第二十七關(Remote add)
添加一個遠端倉庫
第二十八關(Push)
推送本地修改到遠端
第二十九關(Diff)
查看 staging area
和 working directory
中文件的差異。
-
git diff
: 查看working directory
與staging area
之間的差異 -
git diff --cached
: 查看repository
與staging area
之間的差異 -
git diff HEAD
: 查看working directory
與repository
之間的差異
第二十九關
對應 git diff
的顯示結果
第三十關(Blame)
查看某個文件的修改人。這個命令簡直邪惡,鍋終于有人背了!!!
git blame
列出了文件中每行的修改人是誰
第三十一關(Branch)
創建一個分支
第三十二關(Checkout)
創建一個分支,并切換過去。其實,git checkout -b my_branch
就是創建一個分支,并切換過去,而且這種方法更方便,平常用的更多
第三十三關(Checkout tag)
切換到某個特定的 tag
第三十四關(Checkout tag over branch)
切換到某個特定的分支,但是分支名和標簽名重疊了
第三十五關(branch at)
根據一個特定的提交創建新分支
第三十六關(delete branch)
刪除一個分支
第三十七關(Push branch)
將分支推送到遠端倉庫
第三十八關(merge)
合并分支。為了簡化分支模型,可以使用 rebase
代替,后續關卡會遇到。
第三十九關(fetch)
獲取遠端的修改,但是并不合并到當前分支。其實,git pull
就是 git fetch
和 git merge
組成的。
第四十關(rebase)
其實不知道怎么翻譯 git rebase
這個命令。大概意思是從某個提交分化出兩個分支,然后其中一個分支需要將另一個分支的修改合并過來,但是又不想在提交記錄上留下兩個分支合并的痕跡,只留下一個分支以前后順序記錄兩邊的修改。
git rebase
一個分支的所有修改在另一個分支上重新應用一遍,所以在提交記錄上看,會發現一個分支的所有提交在另一個分支之前或者之后。然后刪除另一個被合并的分支,保持分支簡潔。
git rebase master feature
表示將 feature
上的修改在 master
上重新應用一遍
對應第一個 git log --graph -all
,--graph
會用圖形化將提交記錄顯示出來,而--all
會顯示所有分支的提交記錄
對應第而二個 git log --graph -all
,可以發現只保留了一個分支,看起來簡潔了很多。
在使用此命令的時候,需要非常注意的是,不要 rebase 哪些已經推送到公共庫的更新,因為此操作是重新應用修改,所以公共庫的更新可能已經被其他協作者所同步,如果再次 rebase 這些修改,將可能zh
第四十一關(repack)
將版本庫未打包的松散對象打包
第四十二關(cherry pick)
應用某一個提交的修改。
找到我們想要的那個提交,記錄下它的 hash 值
ca32a6dac7b6f97975edbe19a4296c2ee7682f68
第四十三關 (Grep)
git grep
支持各種條件搜索及正則表達式,平時用的不多,但感覺功能強大。
對應 git grep TODO
的結果
第四十四關(rename commit)
重命名提交。當涉及提交修改時,應該想到 git rebase -i
命令,它接受可以一個參數(提交的哈希值),它將羅列出此提交之后的所有提交,然后可以對個個提交做對應的操作。
重命名前的提交記錄
將需要重命名的提交前的 pick
修改為 reword
修改成新的備注,保存并推出
第四十五關(squash)
合并多個提交。
合并前的提交記錄。
將需要合并的提交前的 pick
改成 squash
或 s
。squash
代表并入前一個提交,保存并退出。
為新的提交修改備注
第四十六關(merge squash)
將某個分支上的所有修改都應用成一個提交。默認修改都將進入暫存區
第四十七關
重新排列提交順序。
排序前,對應第一個 git log
在編輯界面,將 Second commit
和 Third commit
的順序調換
排序后,對應第二個 git log
第四十八關
使用 git log
查看所有的提交記錄,太長我就不全貼出來了,找到最開始的提交 f608824888b83bbedc1f658be7496ffea467a8fb
git bisect start master f608824888b83
中,master
是有 bug 的節點,f608824888b83
是沒有 bug 的節點。
第四十九關(Stage lines)
其實,提交文件的部分修改這種需求平時還是比較常見的,不過平時都是用 Source Tree 來操作的,但是看到這題之后,好像又開啟了一扇大門。
第五十關(Find old branch)
git reflog
可以列出所有的操作記錄,所以找到之前忘記的信息并不是什么難事
對應 git reflog
的顯示內容
第五十一關(Revert)
與 reset
不同的是,revert 只會撤銷當前的 commit,而之后的 commit 操作的修改還會保留,但是reset
還會將之后的所有 commit 操作的修改全部退回 staging area 或丟棄。
這是執行撤銷操作前的記錄,對應第一個git log
撤銷操作會生成一個新的 commit,保存并退出即可
撤銷之后的記錄,它不破壞原有的記錄,對應第二個 git log
第五十二關(Restore)
根據之前的經驗,git reflog
可以查看所有的操作記錄,所以只要能找到誤操作之前的 commit id,一樣能夠恢復現場。
執行 git reflog
后畫面如下,根據操作記錄,找到你誤操作的之前的 commit id
第五十三關(Conflict)
沖突處理在平常的協同工作中真是再常見不過了,需要注意的是存在沖突的文件是在 working directory 中的,在解決完沖突之后需要添加到 staging area 并提交。
其實沖突解決完成的圖片丟失了,只能口述了。
<<<<<<< HEAD
到 =======
之間的內容代表 master
分支的修改,=======
到 >>>>>> mybranch
之間的內容代表 mybranch
分支的修改,保留 mybranch
分支的修改,刪除master
分支的修改即可,當然這些特殊符號所在行也要一并刪除。
第五十四關(Submodule)
submodule 是一個很方便的將一個倉庫分解成多個子模塊的命令,特別是項目比較大且依賴其他 Git 項目的時候,比如 Cocos2d-x。雖然好用,但是門檻也相對高點,如果維護好 submodule 還是需要好好研究一下。
第五十五關(Contribute)
其實到這里已經可以算是通關,如果感興趣的話可以到 GitHub 為這個項目貢獻代碼。
結尾
其實這里的所有關卡展示的內容只是 Git 的冰山一角,Git 的魅力遠不止這些,還需我們慢慢探索~
如果文章有表述錯誤,歡迎指正。
最后,感謝這篇文章帶我入坑:
http://gold.xitu.io/entry/5684844560b2cd25b7cb41a3