git 綜合技, 坐時光機解決 CI pre-commit 報錯問題

懂 git 的朋友們可能對 git reset,git checkout,甚至是 git reflog 很熟悉,但有沒有遇過需要綜合使用上述指令的場景呢?這邊分享一個我遇到的情境,可以體會到 git 如電玩進度存檔的魔力。

問題發生在 rebase develop 到我的 feature branch 過程中,因為有 conflict 所以手動修改了一些地方,但 rebase 過程中並沒有 trigger 既有的 pre-commit git hook,導致一些 code style 錯誤的地方沒有檢查到(就是該死的空白行),push 上去後被 ci 擋下。但尷尬的是 ci log 並沒有指出是哪一個檔案出問題,此時該怎麼處理呢?

核心概念就是,想辦法讓這次修改的 code 重新被 pre-commit 檢查過,詳細作法如下:

初始狀態

git 綜合技, 坐時光機解決 CI pre-commit 報錯問題

第一步:踢出修改

我們把 feature branch 中這次的修改從 repository 中全部踢出來。因為剛剛我們才 rebase 過 develop branch,所以直接讓 git 去比對兩隻 branch,就能正確 reset

$ git reset --soft develop
git 綜合技, 坐時光機解決 CI pre-commit 報錯問題

這邊使用 –soft 或使用預設的 mixed 都沒有差異,只是修改的 code 一個到 staged files,一個到 working tree。

可以用 git status 確認一下是不是修改過這些檔案

$ git status

On branch feat
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   orange.py

第二步:跑 pre-commit

確認後,直接 commit

$ git commit -m test

馬上就會 trigger pre-commit,立刻看到 fail

git 綜合技, 坐時光機解決 CI pre-commit 報錯問題

此時再使用 status 查看哪些檔案被 pre-commit 修改過

$ git status

On branch feat
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   xxxxx.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   xxxxxx.py  <= 鬼就是他

第三步:重建 feat branch

知道問題後,我們先重建 feat branch,使用 reflog 查看我們剛剛做過的步驟

$ git reflog

ee05fdc (HEAD -> feat, develop) HEAD@{0}: reset: moving to develop
7014e25 HEAD@{1}: rebase finished: returning to refs/heads/feat
7014e25 HEAD@{2}: rebase: [feat]: add xxxxxx
e4795e4 HEAD@{3}: rebase: [fix]: modify xxxxx

我們現在需要回復到 rebase 完成狀態,所以找到 rebase 指令最後代碼 7014e25,複製起來回到 console 下 reset

$ git reset --hard 7014e25
git 綜合技, 坐時光機解決 CI pre-commit 報錯問題

這邊使用 hard ,讓整個環境像坐時光機一樣回朔到 rebase 完的狀態,此時再去錯誤的檔案隨便加一個空白鍵讓他 commit,pre-commit 就會自動幫你修正啦!

延伸閱讀:
Python 詭譎的 default parameter value ,由踩坑來學習!
被新創公司裁員後,我學到的五件事

參考資料

提升程式碼品質:使用 Pre-Commit (Git Hooks)
[Git] Reset – mixed, hard and soft

Written by J
雖然大學唸的是生物,但持著興趣與熱情自學,畢業後轉戰硬體工程師,與宅宅工程師們一起過著沒日沒夜的生活,做著台灣最薄的 intel 筆電,要與 macbook air 比拼。 離開後,憑著一股傻勁與朋友創業,再度轉戰軟體工程師,一手扛起前後端、雙平台 app 開發,過程中雖跌跌撞撞,卻也累計不少經驗。 可惜不是那 1% 的成功人士,於是加入其他成功人士的新創公司,專職開發後端。沒想到卻在採前人坑的過程中,拓寬了眼界,得到了深層的領悟。