闖過這 54 關,點亮你的 Git 技能樹 (五) - 完結篇


1

這是一個系列文章,介紹學習 Git 的一個小遊戲 - githug,如果你是第一次看到,請先閱讀:
闖過這 54 關,點亮你的 Git 技能樹
闖過這 54 關,點亮你的 Git 技能樹(一)
闖過這 54 關,點亮你的 Git 技能樹(二)
闖過這 54 關,點亮你的 Git 技能樹(三)
闖過這 54 關,點亮你的 Git 技能樹(四)

沒想到第四彈在「開發者頭條」上獲得了 300 多個贊。
看來大家對這個小遊戲挺感興趣的,而且還有不少朋友在促更,今天就讓我們一鼓作氣打通最後的 14 關吧。

同樣,如對任何命令使用有疑問請看第一篇裏的推薦教程,也歡迎在下面留言,我會盡力提供幫助的。

第四十一關


項目時間長了,git 倉庫會慢慢變大,如何優化?
這個場景日常很少用到,而且不是必須用的,所以沒什麼概念。來看一下提示吧!

打開幫助之後輸入 /redundant 搜索關鍵字,一下就找到了一個 -d 的參數。

第四十二關

有一次,我正在一個特性分支上開發一個功能,提交了幾次代碼,就在準備結束合併代碼的時候,然後產品經理說這個需求不用做了。
我強壓下心裏奔騰的一萬隻草泥馬,準備刪除這個分支,但在刪除之前想到有一個 commit 是對一個工具類的修改,還是有用的。
這是我就需要從特性分支上把這個 commit 摘出來,合到 master 分支上,再刪除特性分支。
這個題目就是類似的場景,先來看看特性分支叫什麼,然後找到需要「摘」出來的那個 commit:


查看了一下 log 命令的幫助,發現可以指定分支,這樣就省去了 checkout 到 new-feature 分支的步驟。

上圖中最後的一次提交就是我們需要「摘」出來的,複製它的 Hash。

順利過關!

第四十三關

我們在開發的過程中,爲了不影響當前正在做的事情,會把一些不那麼緊急的任務使用 TODO 註釋在代碼裏,現代的 IDE 都能幫我們識別這些註釋並在一個單獨的窗口中羅列出來。
當然,不借助 IDE,光憑系統命令或 git 命令也是可以做到的。

第四十四關

查看 log,git log --oneline,可以看到中間的 commit message 有一個拼寫錯誤。


看一下提示,可以在 rebase 的時候指定 -i 參數:

查看一下幫助就知道是 interactive 的意思:


在打開的 Vim 窗口中將第一行的 pick 改爲 r,表示:使用 commit,並且修改 commit message。

修正拼寫錯誤的 coommit

第四十五關

當我使用 TDD 方式進行開發,會進行非常頻繁小步的提交,這樣在其他同事看來就缺乏完整性,也會增加後續維護成本。
所以 git 讓我可以在 push 到遠程倉庫之前,對 commit 歷史進行修改合併,把多個 commit 合併成一個。
用 git log --oneline 看一下提交記錄:


從提交記錄可以看出,它提示我們將最後三個 commit 都合併到第二個 commit - Adding README 中。
接着執行 git rebase -i HEAD~4

第一個 commit 爲 pick,後三個改爲 s,意思是使用這個 commit,但將它合併到前一個 commit 中去。
保存退出,會提示我們編輯 commit message,再次保存退出後,查看一下提交記錄:

第四十六關

題目要求在 merge 特性分支時,把所有的新提交合併成一個,先來看看 master 分支當成的狀態:
git log --oneline


再看一下 git log long-feature-branch --oneline

完整過關命令如下:

最後 master 分支狀況如圖,只用一個 commit,包含了 long-feature-branch 所有的修改:

第四十七關

提交順序錯亂時,也可以使用 git rebase -i 進行調整。
先看看 Log,最後兩個提交顛倒了位置:


執行 git rebase -i HEAD~2,將兩行 pick xxx 代碼交換位置即可。

第四十八關

看一下歷史:

代碼中不知道什麼時候引入了 bug,不過沒關係,我們有自動化測試。
我們可以不斷手工 checkout 到某個 commit,結合二分法查找快速定位到引入 bug 的那一個 commit。
不過這種純手工重複的事情,已經包含在 git 的命令中了,就是 bisect


讀一下 git help bisect,可以找到這個例子:

我們知道 HEAD 的代碼是有問題的,而第一個 commit 的代碼是沒問題的。
通過 git log 獲得第一個 commit 的 Hash,就可以執行 bisect 命令:

紅線部分已經清楚地告訴我們是哪個 commit 引入的 bug 了。

第四十九關

有時開發了一個特性沒提交,接着又開發了另一個特性。
作爲一個自律的程序員,應該是要分兩次提交的,如果修改的是不同的文件,那可以輕鬆地通過 add 不同的文件進行兩次提交。
但這次好巧不巧的是居然修改了同一個文件,怎麼辦?看看提示:


原來 git add 的最小粒度不是「文件」,而是 hunk(代碼塊)。
git help add 然後查找 hunk

執行如下命令:

Git 會讓我們有機會選擇對每一個 hunk 做什麼樣的操作。這裏修改同一個位置,在一個 hunk 裏,根據提示我們還要輸入 e 手工編輯 hunk。

將第 5 行刪除,保存退出,再看當前狀態:

git diff --cached

git diff

目的達到了,過關:

第五十關

正在特性分支上開發一個功能,被頭兒叫去修了一個緊急的 bug,修完後發現:媽蛋,那個特性分支叫啥?忘記了!
當然,作爲一個自律的程序員,一般是不是出現這樣的場景的。
這種情況說明分支命名太沒有規律,或者分支太多,不然可以通過 git branch 看一下,也能很快找到特性分支。
先看一下提示吧:


哦,原來有個命令叫 git reflog,來看看幫助文檔 - git help reflog,看起來這個命令非常強大,不過我們這裏只用到簡單用法就可以了:

上圖中第二行就顯示了我們之前工作的特性分支。

第五十一關

有時代碼 push 到遠程倉庫後發現某一塊代碼有問題,我們可以通過 revert 命令將特定 commit 完全恢復。
首先我們要找到需要 revert 的 commit 的 hash:


完全過程如下:

第五十二關

剛剛把最新的一次提交給毫無保留的扔掉,馬上就改了主意,怎麼辦?世界上有後悔藥嗎?
有的,只要進行 git 版本控制的一切都能找得回來。看下提示先:


提示說被我們拋棄的那個 commit 像孤魂野鬼一樣在外遊蕩,還沒有被鬼差送入地獄,我們還能通過 git reflog 找到它的代號。

找到它的 Hash 後就通過 cherry-pick 將它找回來:

第五十三關

衝突合併是使用版本控制非常常見的了,居然在這麼靠後的位置纔出來。


編輯衝突的文件 poem.txt,刪除 Git 添加的標識衝突的行。

別忘了,還要 git add poem.txt 然後 git commit

第五十四關

submodule 是 Git 組織大型項目的一種方式,通常可把第三方依賴作爲 submodule 包含進來,這個 submodule 本身也是一個獨立的 Git 項目。

第五十五關

最後這一關並非測試使用 GitHub 的能力,而是期望大家貢獻代碼,包括增加更多關卡,修復 Bug 或者完善文檔。
我當初是準備翻譯中文版,結果工作量不小,拖的太久最後不了了之了。
希望你能對開源社區貢獻自己的一分力量!哪怕 Star 一下也是對作者莫大的鼓舞!

原文地址:https://codingstyle.cn/topics/181

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章