Git 闖關遊戲——githug
學習 Git 過程中缺乏實踐?不如來玩一玩這款 Git 闖關遊戲,通過 git 命令來闖關。玩着玩着就學會了 Git,美滋滋!
1 githug
githug 是用 Ruby 開發爲了幫助學習使用 git 的一個闖關遊戲。和我之前推薦的學習 Linux 命令的 Bandit 遊戲有點像。
其 Github 地址:https://github.com/Gazler/githug
安裝過程也比較簡單,首先安裝好基本的 Ruby 環境(1.8.7)以上
因爲國內可能會遇到用 gem 安裝相關包因爲 https 網絡問題報錯的情況,如果出現Unable to download data from https://rubygems.org/
這樣的報錯信息
可以通過如下方式解決
sudo gem sources -r https://rubygems.org
sudo gem sources -a http://rubygems.org
當然安裝完以後也別忘了設置回來
sudo gem sources -r http://rubygems.org
sudo gem sources -a https://rubygems.org
然後進行安裝:
sudo gem install githug
安裝完成以後運行githug
會提示創建相關的文件夾,回覆y
就行了。
githug 有 4 個基本命令:
play - 默認命令,查看當前狀態和題目
hint - 給你當前level的一些提示
reset - 重新開始當前關卡
levels - 列出所有關卡
2 通過題解
有一些關卡比較簡單,選取一些我覺得有點意思的關卡給出題解吧。
2.1 20 commit_in_futue
使用一個未來的時間作爲提交,提交的時候指定–date 選項,能夠自定義提交的時間
$ git commit -m "future commit" --date=12.12.2018T22:00:00
[master (root-commit) 2f27bee] future commit
Date: Wed Dec 12 22:00:00 2018 +0800
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README
2.2 21 reset
git reset 常用來進行版本回推。要了解reset
命令首先要了解 git 中的三棵樹:
HEAD
:是當前分支引用的指針,它總是指向該分支上的最後一次提交。 這表示 HEAD 將是下一次提交的父結點。
暫存區(Index)
:預期的下一次提交
工作區
:git 實際管理的文件的目錄
reset
命令以一種簡單可預見的方式直接操縱三棵樹,它做了三個基本操作:移動 HAED,重置索引,重置工作目錄。實際上 reset 是以特定的順序來重寫三棵樹,並在指定相應選項時停止:
- 移動 HEAD 分支的指向 (若指定了 –soft,則到此停止)
- 使索引看起來像 HEAD (–mixed,默認到此停止)
- 使工作目錄看起來像索引 (若指定了 –hard,則進行這一步)
git reset to_commit_second.rb
2.3 22 reset_soft
使用 reset 命令的 –soft 選項
git reset --soft HEAD~
2.4 23 checkout_file
checkout 作用於文件的時候,會將文件從當前 HEAD 中檢出,即讓當前工作區的文件變成 HEAD 中的樣子,命令格式爲git checkout [-q] [<commit>] [--] <paths>...
git checkout config.rb
2.5 30 blame
可以通過 git blame
命令查看項目中具體哪一行代碼是誰寫的,什麼時候引入的。
git blame config.rb
2.6 33 checkout_tag
檢出到指定標籤,通過checkout
命令實現,能夠創建一個臨時分支指向 tag 所在的提交
git checkout v1.2
2.7 34 checkout_tag_over_branch
有的時候會遇到標籤和分支的名字一樣的情況,通過在前面添加前綴tags/
來指定是 tag 的名字
git checkout tags/v1.2
2.8 35 branch_at
檢出指定提交到一個新的命名分支
git checkout -b test_branch HEAD~
2.9 40 rebase
rebase 命令可以用來整合來自不同分支
如上圖所示,提取在 C4 中引入的補丁和修改,然後在 C3 的基礎上再應用一次。在 Git 中,這種操作就叫做 變基
git rebase [<upstream> [<branch>]
命令將 upstream 的修改在 branch 上再應用一次
git checkout feature
git rebase master
2.10 41 rebase-onto
在對兩個分支進行變基時,所生成的 “重演” 並不一定要在目標分支上應用,你也可以指定另外的一個分支進行應用。就像 從一個特性分支裏再分出一個特性分支的提交歷史 中的例子這樣。
$ git rebase --onto master server client
以上命令的意思是:“取出 client 分支,找出處於 client 分支和 server 分支的共同祖先之後的修改,然後把它們在 master 分支上重演一遍”。
當 master 和 server 一致的時候,只需要寫一個
git rebase --onto master wrong_branch
2.11 42 repack
git repack 對鬆散對象進行打包,凡是有引用關聯的對象都被打在包裏,未被關聯的對象仍舊以鬆散對象的形式保存
git repack
2.12 43 cherry-pick
應用某一個提交的修改到當前分支
git checkout new-feature
git log
git cherry-pick ca32a6dac7b6f97975edbe19a4296c2ee7682f68
2.13 45 rename commit
當涉及提交修改時,應該想到 git rebase -i
命令,它接受可以一個參數(提交的哈希值),它將羅列出此提交之後的所有提交,將此提交作爲一個 root commit。用途爲修改提交歷史,其後跟一個某一條提交日誌的哈希值,表示要修改這條日誌之前的提交歷史。
輸入命令以後,會將提交從前到後顯示。每一行的前面有一個命令詞,表示對此次更新執行什麼操作。
類似下面這種:
pick 06973a3 First coommit
pick 771b71d Second commit
前面的命令有以下幾種:
- “pick”,表示執行此次提交;
- “reword”,表示執行此次提交,但要修改備註內容;
- “edit”,表示可以修改此次提交,比如再追加文件或修改文件;
- “squash”,表示把此次提交的內容合併到上次提交中,備註內容也合併到上次提交中;
- “fixup”,和 “squash” 類似,但會丟棄掉此次備註內容;
- “exec”,執行命令行下的命令;
- “drop”,刪除此次提交。
這一關是需要把第 2 次提交錯誤額 comment 修改過來,所以對第二次提交執行 reword 並修改備註就行了
2.14 46 squash
把多次修改合併成一次,這裏用到的還是上面的git rebase -i
的命令,只不過是將後面動作命令都變成squash
2.15 47 merge_squash
爲了把分支的多次提交合併爲主幹上的一次提交,可以在 merge 命令後面加一個 squash 參數
git merge branch-name --squash
過關命令:
git merge long-feature-branch --squash
git commit -m "comment"
2.16 48 reorder
你提交了幾次但是提交順序多了,想把順序換一下,這裏用到的還是git rebase -i
命令。需要把幾次提交的順序更換一下即可。
2.17 49 bisect
在程序持續迭代的過程中不免會引入 bug,除了定位 bug 的代碼片斷,我們還想知道 bug 是在什麼時間被引入的,這時就可以藉助 Git 提供的 bisect 工具來查找是哪次提交引入了 bug。bisect 是用二分法來查找的,就像用二分查找法查找數組元素那樣。
其查找流程也比較簡單,首先確定查找的 commit 範圍,然後在每一次二分查找時給出程序執行是否正確的判斷。這個時候 bisect 就會自動進行二分查找。
$ git bisect start
$ git bisect good f608824888b
$ git bisect bad 12628f463f4
$ make test
$ git bisect good
...
2.18 50 stage_lines
用 git add
命令可以把文件添加到暫存區,但如果你不想把文件中的全部修改都提交到暫存區,或者說你只想把文件中的部分修改提交到緩存區,那麼你需要加上edit
參數
這時 Git 會自動打開文本編輯器,編輯的內容就是 git diff
命令的結果,這時你就可以編輯 2 個文件之間的差異,只保留要提交到暫存區的差異,而刪除不需要提交到暫存區的差異,然後保存退出,Git 就會按你編輯過的差異把相應的內容提交到暫存區。
git add file-name --edit
2.19 51 find_old_branch
使用git reflog
可以查看歷史所在的分支和提交在哪裏
2.20 52 revert
git revert
命令能夠對某一次提交執行逆操作,這適用於某次提交出現問題的情況,添加--no-edit
能夠讓系統自動生成備註
git log
git revert 3873913 --no-edit
2.21 55 submodule
如果你想把別人的倉庫代碼作爲自己項目一個庫來使用,可以採用模塊化的思路,把這個庫作爲模塊進行管理。Git 專門提供了相應的工具,用如下命令把第三方倉庫作爲模塊引入:
git submodule add module-url
git submodule add https://github.com/jackmaney/githug-include-me
3 參考
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://www.liuin.cn/2018/08/08/Git-%E9%97%AF%E5%85%B3%E6%B8%B8%E6%88%8F%E2%80%94%E2%80%94githug/