git commit前檢測husky與pre-commit 提交鈎子


 

git commit前檢測husky與pre-commit

 

git commit前檢測husky與pre-commit - 簡書 https://www.jianshu.com/p/f0d31f92bfab


Prettier · Opinionated Code Formatter https://prettier.io/
{ "husky": { "hooks": { "pre-commit": "pretty-quick --staged" } } }

a@test MINGW64 /d/code/app_wxa (v3.0)
$ ll -as
total 295
  4 drwxr-xr-x 1 Administrator 197121      0 七月 12 22:55 ./
  4 drwxr-xr-x 1 Administrator 197121      0 五月  9 11:53 ../
  4 drwxr-xr-x 1 Administrator 197121      0 七月 12 22:57 .git/
  1 -rw-r--r-- 1 Administrator 197121     32 四月  3 21:29 .gitignore
  1 -rw-r--r-- 1 Administrator 197121    412 四月 26 17:46 .prettierrc
  0 drwxr-xr-x 1 Administrator 197121      0 七月 12 22:55 node_modules/
  0 drwxr-xr-x 1 Administrator 197121      0 七月 12 22:57 app/
  4 -rw-r--r-- 1 Administrator 197121    856 七月 12 22:44 package.json
276 -rw-r--r-- 1 Administrator 197121 278578 七月 12 22:55 package-lock.json
 
a@test MINGW64 /d/code/app_wxa (v3.0)
$ cat .prettierrc
{
    printWidth: 180,
    semi: true,
    tabWidth: 4,
    useTabs: false,
    singleQuote: true,
    trailingComma: "none",
    bracketSpacing: true,
    htmlWhitespaceSensitivity: "ignore",
    parsers: {
        ".jsx": "flow",
        ".scss": "scss",
        ".ts": "typescript",
        ".less": "css",
        ".vue": "vue",
        ".nvue": "vue",
        ".ux": "vue",
        ".yml": "yaml",
    }
}
 
 
a@test MINGW64 /d/code/app_wxa (v3.0)
$ cat package.json
{
    "husky": {
        "hooks": {
            "pre-commit": "pretty-quick --staged"
        }
    },
    "devDependencies": {
        "husky": "^4.2.3",
        "lint-staged": "^10.1.1",
        "prettier": "2.0.2",
        "pretty-quick": "^2.0.1"
    },
    "dependencies": {
        "@babel/core": "^7.9.0",
        "chalk": "^3.0.0",
        "eslint": "^6.8.0",
        "execa": "^4.0.0",
        "find-up": "^4.1.0",
        "ignore": "^5.1.4",
        "jquery": "^3.4.1",
        "miniprogram-sm-crypto": "^0.1.0",
        "mri": "^1.1.5",
        "multimatch": "^4.0.0",
        "node-rsa": "^1.0.8",
        "npx": "^10.2.2",
        "prettier": "^2.0.2",
        "pretty-quick": "^2.0.1",
        "trim": "0.0.1",
        "vue": "^2.6.11",
        "yaml": "^1.8.3"
    },
    "lint-staged": {
        "*.{js,css,md}": "prettier --write"
    }
}
 
 
git commit前檢測husky與pre-commit - 簡書 https://www.jianshu.com/p/f0d31f92bfab

prevent commit時,我們可以把eslint以及test命令加上,檢測代碼規范:

"scripts": {

 "precommit": "lint-staged && npm run test" 


 
https://www.npmjs.com/package/pre-commit https://www.npmjs.com/package/pre-commit
 
 
git commit觸發的hook - 簡書 https://www.jianshu.com/p/b532d62da0f1

git中提供了一組hook,規定了每個hook的名字,以及hook接收的參數個數和每個參數的含義。用戶如果要使用hook的話,需要在.git/hooks/目錄中創建對應名字的hook文件,賦予該文件可執行權限,用bash或者python或者其它腳本語言來實現該hook具體要做哪些事。hook就是類似於onClick()、onRun()這樣的事件,也可以理解成是一組回調函數。

git commit是最常用的命令之一,它可以觸發四個hook,分別是pre-commit,prepare-commit-msg,commit-msg和post-commit。從字面上可以猜測到這四個hook分別對應“commit之前”、“准備commit log message的時候”、“生成commit log message的時候”、“commit之后”這四個觸發時機。這四個hook也的確是按照這個先后順序被觸發的。如果git commit時使用了-n(等價於--no-verify)參數的話,pre-commit和commit-msg就不會被觸發。

pre-commit不接收參數。這個hook可以用來在commit之前檢查修改的代碼是否符合規范、檢查文件名是否含有空格、或者僅僅單純地輸出“hello world”等等,具體想要做什么可以根據實際情況來決定。如果以非0狀態退出的話,譬如檢測到文件名中有空格,而用戶不希望這種文件被commit,在這種情況下執行exit 1,那么git commit會以失敗而終止。

prepare-commit-msg接收三個參數。第一個是commit log message所在的文件名,通常是.git/COMMIT_EDITMSG。第二個是commit log message的來源。在《git commit中輸入message的幾種方式》 中有介紹過-m,不加參數,-c,-C,-F,-t等方式輸入commit log message,這些都是不同的來源。如果是-m的話,第二個參數的值是"message";如果是不加參數的話,第二個參數的值是"";如果是-c或-C或者其他情況但加了--amend參數的話,第二個參數的值是"commit";如果是-F的話,第二個參數的值是"message";如果是-t或者設置了commit.template的話,第二個參數的值是"template"。

如果第二個參數不是"commit",那第三個參數值為""。如果第二個參數值是“commit"的話,那第三個參數值就是-c或者-C后面接的那個值,可能是tag name、branch name、HEAD、HEAD^1、具體的某個commit SHA-1等等。有--amend的話,第三個參數值是"HEAD"。

此外,git merge和git cherry-pick可能會觸發這個hook。git merge如果是ff(fast-forward) merge那不會觸發這個hook,但如果發生no-ff類型的merge,或者git merge --no-ff,那么會觸發這個hook,第二個參數值為"merge";git merge --squash && git commit的情況下,第二個參數值為"squash"。git cherry-pick默認情況下會觸發這個hook,除非使用了-n(等價於--no-commit)參數,第二個參數值為"message"。

理論上來說,pre-commit中的事情可以放到prepare-commit-msg中來做,但不推薦這么做 。prepare-commit-msg的設計本意是在commit-msg之前編輯message文件用的。譬如,希望在commit log message中記錄下當前某個系統的某些狀態值(譬如jenkins上某個編譯job的環境變量和用戶變量),那可以在prepare-commit-msg中對准備用於-F或者-t的文件進行編輯,將那些實時獲取的狀態值插入到文件中去。然后這個文件的內容會被寫入.git/COMMIT_EDITMSG,commit成功以后,這些內容就變成了commit log message的一部分。當然,這些內容也可以在git commit之前組織好,然后在git commit的時候直接用起來。但如果放在hook里來做,就等於封裝到了git commit的內部。用戶可以根據實際情況考量是否需要用這個hook。同樣的,這個hook如果以非0狀態退出的話,會使git commit失敗而終止。

和prepare-commit-msg比起來,commit-msg使用的場景更多些。這個hook接收一個參數,commit log message所在的文件名,通常是.git/COMMIT_EDITMSG。從這個文件中,可以讀取到最終運用於commit log message的內容。比較常見的運用是在這里檢查commit log message是否符合事先規定的格式。另外一個實際運用是使用gerrit系統的場合下,git commit時會根據已有的信息生成一個類似commit SHA-1的Change-Id,並將其插入到commit log message中去。生成Change-Id的算法會用到用戶編輯完成后的commit log message的內容,所以生成Change-Id的動作不能在commit-msg之前做。同樣的,這個hook如果以非0狀態退出的話,會使git commit失敗而終止。

post-commit在commit完成后被觸發,不接收參數。post-commit能夠執行,說明git commit已經成功了。接下來可以做很多事,譬如執行git push到一個備份branch上,或者啟動編譯,或者關機(每天只做一個commit),或者也可以很無聊地git reset --hard回到新生成的commit的parent上(這么做毫無意義),也可以把硬盤格式化掉(再見!)

要試驗這四個hook的話,可以在.git/hooks/下創建四個文件,文件名分別為pre-commit,prepare-commit-msg,commit-msg,post-commit,將它們都改為可執行文件。假如要用hook打印每個hook接收了哪些參數:

#!/usr/bash

echo $@

或者

#!/usr/bin/env python

import sys

print sys.argv

然后執行各種git commit看看效果吧。別忘了每個hook的參數列表第0個是hook文件的路徑,后面才是接收的參數。hook是一扇門,你的腦洞有多大,門后面的世界就有多大。

 
 
Git - Git Hooks https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
 
 git hook實現代碼自動部署_君君的專欄-CSDN博客_git hook https://blog.csdn.net/u010837612/article/details/70825225
  1. git用戶執行git push操作
  2. 遠程倉庫發現有用戶執行了push操作,就會執行一個腳本post-receive(鈎子)
  3. post-receive腳本中,將git倉庫的代碼拷貝到web站點目錄下

 

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM