# 初探Git Hooks,優化Git工作流 ###### tags: `vic的blog文章` blog網址: https://yoshuu.github.io/2023/05/04/git-hooks-introduction/ git是現在主流的版控控制,寫軟體的人基本上都知道,但關於如何優化工作流以及什麼是git hooks知道的人可能就不多,因為這個部分是一種「優化」,使用了會更好,但是不用也沒關係,那我研究後覺得git hooks學會之後好處很多,那下面會儘量用好懂的方式來記錄跟介紹。 不講腳本寫法,不講複雜應用,只講整體的概念以及簡單的小應用來幫助理解概念。 但還是要有對於git的簡單知識,不然可能看不懂這篇。 這篇文章主要會有以下這三個大重點: - 什麼是git hooks - 為什麼要使用git hooks - git hook基本的應用有哪些 ## 什麼是git hooks 用一句話來講解這個概念,就是「每次使用了git的資料庫中發生特別事件時(像生命週期)自動運行的腳本」。 生命週期就是像人的一生中,有嬰兒、壯年,生、老、病、死,那git的特別事件我覺得也像是生命週期一樣,就是git的一些重要環節上代表各個git的生命週期,這個稍微就會解釋。 腳本就是一種程式的文件,我會把它想像是可以做某一種事情的程式,像是玩遊戲的時候,假如覺得一直在做一些重複性的事情很煩,那就可以寫一個滑鼠自動一直點的腳本。 而使用了git的資料庫的話,就是一個乾淨的專案裡面,只要下一個指令`git init`,那這個專案就會被加入到git的版控中,然後專案目錄下也會多出一個.git的隱藏檔。 好,然後下一個問題我想就是那該如何去之後這個腳本會怎麼運行? 我得去哪裡控制它? 首先,會在它git專屬的隱藏檔裡面,在`.git/hooks`的位置,可以在裡面去放入腳本來去進行控制的動作,但要注意,一般來說是觀測不到的,因為git的.git隱藏檔是預設看不到,所以要使用git hooks的技術,第一步得先找到git hooks檔案所需要放置的位置。 以下是打開git隱藏檔,找出git hooks的方式,我是用vscode,所以只講它的情境:  一開始打開vscode, => 設定 (右下角齒輪裡面,蠻明顯的,按下去再使用者那邊找) => 找Files: Exclude => 如上圖,刪除裡面.git選項 這樣一來,你就會發現隱藏檔露出了它的廬山真面目,但注意的是,因為這種改動從設定(使用者)的話是影響整個專案,而之所以git隱藏檔要隱藏起來,是因為不小心亂改到是很危險的,所以如果用這種方式改的話,那之後所有的專案都可以看到的。 這邊也提供另外一個技巧,如果你今天只想for自己的這個專案可以看到的git隱藏檔,可以這樣做。 一樣進到設定,但不是使用者,而是它右邊的工作區,點擊進去工作區之中的`settings.json`,加上這一段程式碼就ok了。 ``` { "files.exclude":{ "**/.git": false, } } ``` 當成功的把git的隱藏檔顯露出來後,就可以觀測到git hooks的所在。  一個名字叫做hooks的資料夾,裡面擺了很多的git生命週期事件的檔案,等等會把這個檔案跟git的真正對應指令做個比較圖,先講這邊要如何去修改跟撰寫。 其實很簡單,就是把這個檔案的`sample`給刪除,直接去更改裡面就會生效了,我的理解是`sample`是要讓它預設為沒作用,那拿掉就變成有作用。  另外裡面打開會長這個,除了最上面的`#!/bin/sh`之外其他都刪除也沒關係,我都會先把預設的都刪掉然後再自己寫新的,還有就是裡面寫的腳本可以用任何的程式語言去寫,像是node.js也是完全沒問題。 接下來這邊最後就來講裡面的各種檔案對應的git指令吧:  有很多,但我只列舉git的最常用的那幾個,像是耳熟能詳的`git add`、`git commit`這種,而我們想要利用git hooks做的事情,其實就是當我們在使用這些git指令的時候,可以在那個時期做事情而已,也就是執行腳本。 會發現hit hooks裡面的特定檔案事件會把git指令分成執行前以及執行後,初看會覺得似乎沒有必要,但這卻是必須的。 我來舉例一個情境,假如你使用腳本,是為了在`git commit`之前去做檢查,要是commit訊息中,沒有某些字,你要用git hooks腳本的方式,阻止coomit訊息的發送,那麼同樣的腳本,執行前跟執行後就分成兩種不同的情境。 `git commit`執行之前的話,那代表還沒有成功commit,所以腳本檢查完去阻止,是可以成功擋下的, 但是在`git commit`執行之後的話,它git生命週期的點已經是commit結束之後了,就算可以檢查得出錯誤,但也沒辦法阻止發生,這是它一個很大的差別。 所以說,執行前有它的情境,執行後也有它的用處,這是兩種不同的卻又都有需求,兩個都要有很合理。 ## 為什麼要使用git hooks 關於這個部分,我有整理出了幾點: 1. 自動化流程 2. 強制規範 3. 安全性 第一,自動化流程的意思是使用Git hooks可以自動化許多重複性、瑣碎的工作。 沒有也可以,但你就是要手動一直做很多重複事情,軟體開發時總是會遇到這種事情,像是運行單元測試、檢查代碼風格、自動化部署等等,會發現這些事情可能超級耗時間,而且因為是手動去執行的,所以會發生一些像是忘記執行,或是少執行了一些步驟,然後導致整個在使用版控的流程發生錯誤。 git hooks只要把這個自動化的流程流程寫成腳本,放進去git的生命週期,像是每次push之後都要做一個自動化部署,直接幫你省一大堆時間,開發效率直線上升。 接著是強制規範的部分,Git hooks可以強制做一些規範,像是說查程式碼風格、檢查文件格式、防止不必要的合併等等,甚至連git commit訊息都可以去規定它要怎麼寫,用了就回不去了,實在是太方便。 這樣做可以確保假如有在協作的話,大家全部人的風格都符合同一個標準,有一致性的同時也拉高了可讀性,讓寫code變成更愉快的同時,程式碼也是變的用容易維護以及修改。 最後是安全性,Git hooks可以幫助保持資料庫的安全性,例如說防止提交敏感資訊、防止執行有害的程式碼等等。 像是如果有不能被傳上去的禁止字樣,或是可怕的程式碼寫法,直接上傳上去是會造成困擾的,這個部分跟強制規範規範其實有點類似,主要就是在提交程式碼之前,再次做個檢查,看看這些程式中有沒有包含危險不安全的東西存在,有的話就馬上警告,確保整個專案都是安全的狀態。 總之,做個小結論,使用Git hook可以幫助自動化流程、強制規範和提高安全性,從而提高開發效率、確保品質和減少風險,不用可以,用了會更好,這是我覺得它的優點。 ## git hook基本的應用有哪些  這邊最基礎的話,從`pre-commit`開始寫起git hooks,也就是所謂的`git commit`執行之前的腳本,跟前面說的一樣,除了最上面那行之外,其他全部刪掉,自己寫。 我這邊寫的意思是,當coomit的指令下出去,指令之後,執行之前會去跑這個腳本觸發,功能是會呼叫一次我的名字,"hello vic"這樣。 有用到了兩個我覺得要知道的語法,介紹一下什麼是`Echo`及`exit`。 `Echo`命令用來將後方參數輸出到console,就是把寫的東西印出來。 `exit`命令如果是0的話會讓commit繼續,若exit後為非0,例如exit 1則會終止commit。  然後是稍微讓大家了解概念的應用,也就是執行腳本這件事情,專案當中,可能就已經使用了很多`lint`系列的套件,這些套件就是專門用來負責處理程式的格式、風格,所以其實可以把它們直接加上git hooks就好了。 舉例來說,假如專案中有在使用`eslint`,通常Node.js專案會在package.json的scripts欄位下設定lint腳本,來呼叫lint工具去檢查JavaScript等程式碼的語法。 那我可以把它搭配做使用,在git hooks當中的pre-commit腳本中去執行npm run lint。 這樣就會達成效果是commit指令下去之後,會在commit執行之前,幫我得程式碼做一個檢查的動作,這也是我目前比較常用的做法,然後commit的話也有專門的commitlint可以做使用,所以其實不用真的會寫git hooks的腳本也沒關係。 ## 小結 以上大致就是我在研究git hooks之後,想分享及做的筆記心得,下次可能會想研究git hooks的工具搭配,因為其實要打開隱藏檔這件事情真的是比較麻煩的,而且由於.git隱藏檔不吃版控的關係,我找了一些奇怪的方式才能追蹤到推遠端,覺得應該可以用更好的方式。 有一個叫做`Husky`的工具,據說使用它可以讓git hooks這件事情變得更加簡單,下一個研究的目標就會是它,研究完我會再把我的心得研究丟blog。 ## 參考資料 ### 影片類 [(2) [Git#8] 用pre-commit檢查提交時的分支是否正確 - YouTube](https://www.youtube.com/watch?v=zKR3I9t9KF0&ab_channel=%E7%B0%A1%E7%9D%BF%E5%AD%B8%E5%A0%82) [透過工具建立有規範的 git commit message 吧 - YouTube](https://www.youtube.com/watch?v=ZQFvw3Rfhpg&t=251s&ab_channel=PJCHENder) ### 文章類 [Git - Git 鉤子](https://git-scm.com/book/zh-tw/v2/Customizing-Git-Git-Hooks) [菜鳥工程師 肉豬: Git 什麼是Git Hooks?](https://matthung0807.blogspot.com/2021/08/what-is-git-hooks.html) [aitemr/awesome-git-hooks: 😎 A collection of awesome Git Hooks](https://github.com/aitemr/awesome-git-hooks) [手写 git hooks 脚本(pre-commit、commit-msg)](https://www.freecodecamp.org/chinese/news/git-hooks-script/) [探索藏在Git當中的Git Hook - HackMD](https://hackmd.io/@s716134/githook01#fn1) [如何在執行git commit前自動進行檢查?Git Hooks的基本用法 | MagicLen](https://magiclen.org/git-hooks/)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.