gitの便利なfilterまとめ
gitのfilterは、checkout時 と add時 に任意のフィルターをかけることができる。
概念図
$Gcid$にコミットIDを埋め込むフィルターを作ってみる
やりたいこと
git checkout時に指定ファイルの、
echo "$Gcid$"
→echo "$Gcid: bcc4bbe68b26a65a1597752a$"
に展開。
git add時は逆に、
echo "$Gcid: bcc4bbe68b26a65a1597752a$"
→echo "$Gcid$"
に戻す。
手順
- gitの設定でfilterを定義 (.git/config)
- フィルターの対象を定義 (.gitattributes)
- フィルター時に実行するスクリプトを用意 (embed-commit-id.rb)
- フィルターされるファイルを用意 (fuga.sh)
- 試す
. ├─ .git/config (~/.gitconfigでも/etc/gitconfigでも) ├─ .gitattributes ├─ embed-commit-id.rb └─ fuga.sh
1. gitの設定でフィルターを定義 (.git/config)
フィルターの設定をする。
$ vi .gitconfig [filter "embed-commit-id"] smudge = ruby embed-commit-id.rb clean = perl -pe \"s/\\\\\\$Gcid[^\\\\\\$]*\\\\\\$/\\\\\\$Gcid\\\\\\$/\"
2. フィルターの対象を定義 (.gitattributes)
フィルターをかけるファイルを指定する。
$ vi .gitattributes fuga.sh filter=embed-commit-id
3. フィルター時に実行するスクリプトを用意 (embed-commit-id.rb)
smudgeフィルターで実行するスクリプト
$ vi embed-commit-id.rb #! /usr/bin/env ruby puts STDIN.read.gsub('$Gcid$', '$Gcid: ' + `git rev-parse HEAD`.strip + '$')
4. フィルターされるファイルを用意 (fuga.sh)
フィルターされるファイルに、変数を埋め込む。
$ vi fuga.sh echo "$Gcid$"
ここで一旦全部コミットしておく
5. 試し
変数は未展開
$ cat fuga.sh echo "$Gcid$"
checkoutする
$ rm fuga.sh $ git checkout fuga.sh
チェックアウトを経由するとフィルターにより展開される
$ cat fuga.sh echo "$Gcid: 3c6c5646726ba5948a9c0198f856bdce0be330de$"
変更してaddしてみる
$ echo "fuga" >> fuga.sh $ git add fuga.sh
addするとフィルターにより変数が元に戻り差分が出ない
$ git diff --cached echo "$Gcid$" +fuga (もちちんcheckoutじゃなくてcloneでも同様の効果が得られる)
まとめ
スタイルチェック通らないとaddできないようにするとか、
任意のスクリプトをcheckout/add時に動かせるので色んなことが出来そう。