shell script in pre-commit


Posted by tsungtingdu on 2021-09-18

問題

上週遇到的一個問題是,在 local 開發的時候,為了要加快開發速度,因此需要特別調整檔案裡面的某個值(很可惜的,這個值沒有辦法透過 env 檔案的切換來替代),然而,我又不希望工程師不小心把這個變動也 commit 進去,因此希望能在 pre-commit 的階段就可以先擋下來。

於是我就寫了下面這樣簡短的 shell sciprt 並放在 .git/hooks/pre-commit 裡面

解法

#!/bin/bash

CHANGEDFILES=$(git diff --cached --name-only --diff-filter=ACM)
INVALIDFILES=0

for FILE in $CHANGEDFILES
do
  if [[ "$FILE" =~ (app.routing.module.ts|app.module.ts) ]]; then
     VALUE=`cat $PWD/$FILE`

     if [[ "$VALUE" =~ (foo|bar) ]]; then
      echo "DO NOT commit $FILE with foo or bar"
      $((INVALIDFILES += 1))
     fi
  fi
done

if [[ "$INVALIDFILES" > 0 ]]; then
  exit 1
fi

exit 0

分解動作

收集有被更動、準備要被 commit 的檔案

CHANGEDFILES=$(git diff --cached --name-only --diff-filter=ACM)

建立一個變數,收集 invalid 檔案的數目。初始值為 0

INVALIDFILES=0

用一個 for loop 來遍歷剛剛收集到的檔案們

for FILE in $CHANGEDFILES
do
 ...
done

用 if 來判斷這些檔案當中,是否有我們的目標檔案

  if [[ "$FILE" =~ (app.routing.module.ts|app.module.ts) ]]; then
     ...
  fi

若有,則先將該檔案的資料讀取出來。這裡的檔案路徑採用 $PWD/#FILE 以取得完整路徑

VALUE=`cat $PWD/$FILE`

接著,如果檔案裡面有我們不想要的值(譬如 foo 或是 bar),那麼就印出警告訊息,同時讓變數 INVALIDFILES 加 1

 if [[ "$VALUE" =~ (foo|bar) ]]; then
  echo "DO NOT commit $FILE with foo or bar"
  $((INVALIDFILES += 1))
 fi

最後,如果 INVALIDFILES 大於零,就代表有 invalid 的檔案,所以就用 exit 1 終止執行,檔案也就不會被 commit 進入 git 的紀錄當中。若 INVALIDFILES 為 0,那麼就會執行 exit 0,讓 commit 順利完成。

if [[ "$INVALIDFILES" > 0 ]]; then
  exit 1
fi

exit 0

參考資料

我主要參考《Bash 脚本教程》 變查邊做,不過剛剛也找到一些可以參考的網站:


#shell #Git







Related Posts

COSCUP 2021 筆記

COSCUP 2021 筆記

[PHP] 上傳大頭照的功能

[PHP] 上傳大頭照的功能

建立屬於你的 Google Map 地圖標記(三) - 地址輸入與座標取得

建立屬於你的 Google Map 地圖標記(三) - 地址輸入與座標取得


Comments