個人情報を含むExcel/Wordのgitコミットを禁止

概要

  • ExcelやWord等のMSオフィスファイルをgitにコミットする際、知らず知らずのうちに個人情報を含めてしまう場合があります。
  • 一方で、gitではコミット時にスクリプトを実行できるgitフックの機能があり、この機能を使用してコミット時のチェックを実装することができます。
  • ここでは、オフィスファイルに個人情報が含まれていないかをチェックするgitフック用スクリプトを紹介します。

詳細

gitフックとフックスクリプトの仕様

  • gitコマンドは、コミット対象のファイルパス(複数)を引数として、フックスクリプトを実行します。
    実行結果が、正常(終了コードが0)の場合、gitコマンドはコミットを実行します。異常(終了コードが0以外)の場合、gitコマンドはコミットを中断します。

  • フックスクリプトでは、引数で渡されたファイル内に会社名や名前等の特定キーワードを検索します。キーワードが見つからない場合は正常終了、見つかった場合は異常終了します。
  • ExcelやWord等のMSオフィスファイル(xlsx, docx, pptx等)の実体は、ZIP圧縮されたXMLファイルです。そのため、処理対象がこれらのファイルの場合、ZIP解凍した内容からキーワードを検索します。なお、古いオフィスファイル(xls, doc, ppt等)は違う形式のバイナリになっており動作未確認です。
    NDW*

    PowerPointで「個人情報の削除」を実行するとこで、作成者や会社名等の個人情報を削除できます。しかしながら、特定の…

  • Windows 10環境で動作確認しています。

使用方法

  1. 使用する場合、フックスクリプトのファイル名を”pre-commit”に変更します。
  2. フックスクリプトの内のkeywordsの値に、名前、組織名などのキーワードを指定します。
  3. フックスクリプトを配置します。
    • 個人設定として使用する場合、”.git/hooks”等の既定のフックフォルダに配置します。
    • 独自フォルダに配置する場合、”~/.gitconfig”等の設定値core.hooksPathに、そのフォルダを指定します。
    • プロジェクト設定として使用する場合、”.git/hooks”に配置します。
  4. 動作確認時、失敗するとそのキーワードを含むファイルがコミットされてしまいます。そのため、最初に無害なキーワード(本来のキーワードが日本語を含む場合は日本語)で動作確認を行った後に、正しいキーワードを指定することをお薦めします。

フックスクリプト

完全なソースコードは、githubで公開しています。

#!/bin/sh
#
# pre-commit.sample    特定キーワードを含む場合はコミット中止
#

# NGキーワード(grepオプションのため、"\|"で区切る)
keywords="ichiro\|yamada\|山田\|一郎"

# MS Officeファイルはzip解凍して検証(zip圧縮されたXMLのため)
unzip_exts=('xlsx' 'docx' 'pptx')

# 検証を行う関数
function validate_file() {
    if [ $1 -ne 0 ]; then
        echo "contains NG keyword: $2"
        let failed++
    fi
}

# コミット対象のファイル群を検証
failed=0
filepaths=$(git diff --cached --name-only)
for filepath in ${filepaths[@]}; do

    # ファイル名とその拡張子を取得
    filename=$(basename $filepath)
    ext="${filename##*.}"
    
    # 拡張子に基づいてキーワードの有無を検証
    # (基本的にgrep検索時の該当件数(-c)が0以外は検証NG)
    found_unzip_ext=`printf "%s\n" "${unzip_exts[@]}" | grep -Fxc $ext`
    if [ $found_unzip_ext -ne 0 ]; then
        validate_file `unzip -p $filepath | grep -c $keywords` $filepath
    else
        validate_file `grep -c $keywords $filepath` $filepath
    fi
done

# 検証に失敗している場合はコミット中止
if [ $failed -ne 0 ]; then
	echo "the number of rejected: $failed"
	exit 1
fi