lint-staged如何作到只lint staged?

介紹

lint-staged針對暫存的git文件運行linters而且不要讓 💩 進入你的代碼庫!git

開始

去年分享過一個主題——規範化工做流之約定式提交,主要內容是提交代碼時對暫存區代碼格式的校驗和提交信息規範校驗。當時就接觸到了lint-staged,只知道這個工具能針對暫存區的文件處理,並未深刻了解, 那時候就有一些疑問埋在內心,最近得空,特來解疑。bash

疑問點:app

git分爲暫存區和工做區,若是一個文件同時存在在兩個區(某文件git add後又再次修改,以下圖test2.js ),此時本地的文件內容其實是等同未暫存區的,根據介紹lint-staged會lint暫存區的那個版本,那麼這是怎麼作到的呢?工具

hasPartiallyStagedFiles

先猜想:ui

使用SourceTree提交代碼偶爾會比較卡,稍微窺得點兒(未暫存文件消失再重現),所以猜想多是用了什麼方法先清除未暫存文件而後再恢復。spa

猜想歸猜想,仍是要驗證一下。eslint

結論

通過分析,lint-staged在執行檢查前會保存當前文件狀態,而後清除掉修改,再執行lint任務,執行完畢再恢復。code

重點就是:如何保存?如何恢復?orm

我總結出lint-staged的流程大體以下cdn

flow

這樣就很清晰了,由圖可知,上述疑問點爲紅色流程部分,下面咱們來分析一下流程中的具體實現。

分析

流程大體分爲四部分:

  • Stashing changes
  • Running linters
  • Updating stash
  • Restoring local changes

咱們來分別看一下每一步作了什麼

保留案發現場並清除干擾(Stashing changes...)

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已經被清除(以下圖)。

gitStashSave

執行代碼檢查任務(Running linters...)

按照配置的命令走,好比配置了 "*.js": "eslint"

eslint test2.js test.js
複製代碼

linters

更新(Updating stash...)

上一步(Running linters)若是有檢查到錯誤,直接跳過走下一步(Restoring local changes)

git write-tree // 獲得 formattedIndexTree  
複製代碼

這裏須要特別聲明一下,

若是上一步(Running linters)未檢測到錯誤,那麼這裏獲得的formattedIndexTree 會和第一步的indexTree同樣,若是檢測到錯誤並將修復後文件添加到暫存區,如配置命令是eslint --fix , git add的話,那麼代碼被修復過,formattedIndexTreeindexTree不一樣

恢復案發現場(Restoring local changes...)

git read-tree $workingCopyTree // 首先恢復工做區內容,對應第一步的git add .
git checkout-index -af // 清除工做區修改
git read-tree $formattedIndexTree // 恢復暫存區內容 
git apply $patch // 若是修復了代碼,也應用到工做區
複製代碼

總結

歸根結底,都是git對象的操做。

相關文章
相關標籤/搜索