lint-staged針對暫存的git文件運行linters而且不要讓 💩 進入你的代碼庫!git
去年分享過一個主題——規範化工做流之約定式提交,主要內容是提交代碼時對暫存區代碼格式的校驗和提交信息規範校驗。當時就接觸到了lint-staged
,只知道這個工具能針對暫存區的文件處理,並未深刻了解, 那時候就有一些疑問埋在內心,最近得空,特來解疑。bash
疑問點:app
git分爲暫存區和工做區,若是一個文件同時存在在兩個區(某文件git add後又再次修改,以下圖test2.js ),此時本地的文件內容其實是等同未暫存區的,根據介紹lint-staged會lint暫存區的那個版本,那麼這是怎麼作到的呢?工具
先猜想:ui
使用SourceTree提交代碼偶爾會比較卡,稍微窺得點兒(未暫存文件消失再重現),所以猜想多是用了什麼方法先清除未暫存文件而後再恢復。spa
猜想歸猜想,仍是要驗證一下。eslint
通過分析,lint-staged
在執行檢查前會保存當前文件狀態,而後清除掉修改,再執行lint任務,執行完畢再恢復。code
重點就是:如何保存?如何恢復?orm
我總結出lint-staged的流程大體以下cdn
這樣就很清晰了,由圖可知,上述疑問點爲紅色流程部分,下面咱們來分析一下流程中的具體實現。
流程大體分爲四部分:
咱們來分別看一下每一步作了什麼
git write-tree // 獲得 indexTree
git add .
git write-tree // 獲得 workingCopyTree
git read-tree $indexTree
git checkout-index -af // 清除文件修改(未暫存的test2.js被清除)
複製代碼
根據以上操做步驟得知,lint-staged
經過tree對象
來保存暫存區目錄和工做區目錄,並清除掉工做區修改文件,操做完成後,能夠看到,被修改的test2.js
已經被清除(以下圖)。
按照配置的命令走,好比配置了 "*.js": "eslint"
eslint test2.js test.js
複製代碼
上一步(Running linters)若是有檢查到錯誤,直接跳過走下一步(Restoring local changes)
git write-tree // 獲得 formattedIndexTree
複製代碼
這裏須要特別聲明一下,
若是上一步(Running linters)未檢測到錯誤,那麼這裏獲得的formattedIndexTree
會和第一步的indexTree
同樣,若是檢測到錯誤並將修復後文件添加到暫存區,如配置命令是eslint --fix , git add
的話,那麼代碼被修復過,formattedIndexTree
與indexTree
不一樣
git read-tree $workingCopyTree // 首先恢復工做區內容,對應第一步的git add .
git checkout-index -af // 清除工做區修改
git read-tree $formattedIndexTree // 恢復暫存區內容
git apply $patch // 若是修復了代碼,也應用到工做區
複製代碼
歸根結底,都是git對象的操做。