[[pre-pushフック]]の挙動を確認したい。特に標準入力の内容。
## リポジトリ作成
[[GitHub]]にリモートリポジトリを作ってスタート。
```console
git clone
[email protected]:tadashi-aikawa/pre-push-sandbox.git
cd pre-push-sandbox
```
## pre-push
フックファイル。pushが成功してほしくないので必ず失敗させる。
```console
cat > .git/hooks/pre-push << 'EOF'
#!/bin/sh
remote="$1"
url="$2"
echo "${remote}"
echo "${url}"
echo "-----------"
while read -r local_ref local_oid remote_ref remote_oid; do
echo "============"
echo "${local_ref}"
echo "${local_oid}"
echo "${remote_ref}"
echo "${remote_oid}"
echo "============"
done
exit 1
EOF
chmod +x .git/hooks/pre-push
```
## 基本
### コミットを2つ
まずは変更してコミット。
```console
echo hoge > README.md
git add .
git commit -m hoge
echo hoge >> README.md
git add .
git commit -m hoge
```
```console
$ gls
● f934eb8 (HEAD -> main) hoge
● cfbbfea hoge
```
### pushしてみる
```console
$ git push
origin
[email protected]:tadashi-aikawa/pre-push-sandbox.git
-----------
============
refs/heads/main
f934eb81bbef9932f1a55c32bd62b6b798b37bec
refs/heads/main
0000000000000000000000000000000000000000
============
error: failed to push some refs to 'github.com:tadashi-aikawa/pre-push-sandbox.git'
```
`${local_oid}`はコミットする最新のハッシュがとれてそうだが、`${remote_oid}`はリモートブランチにコミットが存在しないせいか不定値になる。
ここは一度hookを無効化してpushする。
### もう一度コミット
```console
echo hoge > README.md
git add .
git commit -m hoge
echo hoge >> README.md
git add .
git commit -m hoge
```
```console
$ gls
● c59d73e (HEAD -> main) hoge
● 57f7e9b hoge
● f934eb8 (origin/main) hoge
● cfbbfea hoge
```
### もう一度push
```console
$ git push
origin
[email protected]:tadashi-aikawa/pre-push-sandbox.git
-----------
============
refs/heads/main
c59d73e41ced296973b946e92ed9c30e82dd576b
refs/heads/main
f934eb81bbef9932f1a55c32bd62b6b798b37bec
============
error: failed to push some refs to 'github.com:tadashi-aikawa/pre-push-sandbox.git'
```
今度はoriginとlocalそれぞれの場所がハッシュで取得できる。
一度リセットして少し戻す。
```console
$ git reset --hard f934
HEAD is now at f934eb8 hoge
```
```console
$ gls
● f934eb8 (HEAD -> main, origin/main) hoge
● cfbbfea hoge
```
## ブランチ
ブランチを作成した場合の挙動を確認。まずは作成とコミットまで。
```console
git switch -c branch1
echo hoge > README.md
git add .
git commit -m hoge
echo hoge >> README.md
git add .
git commit -m hoge
```
```console
$ gls
● 3dfee82 (HEAD -> branch1) hoge
● c2b7ac3 hoge
╭─╯
● f934eb8 (main, origin/main) hoge
● cfbbfea hoge
```
pushする。
```console
$ git push -u origin branch1
origin
[email protected]:tadashi-aikawa/pre-push-sandbox.git
-----------
============
refs/heads/branch1
3dfee820950c68e6e62448541cb30d7af72565b1
refs/heads/branch1
0000000000000000000000000000000000000000
============
error: failed to push some refs to 'github.com:tadashi-aikawa/pre-push-sandbox.git'
```
やはりリモートがないとこうなる。
## サンプルコードを読み解く
`.git/hooks/pre-push.sample`について。
```bash
#!/bin/sh
remote="$1"
url="$2"
# 0000000000000000000000000000000000000000
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
while read local_ref local_oid remote_ref remote_oid
do
if test "$local_oid" = "$zero"; then
# Handle delete
:
else
if test "$remote_oid" = "$zero"; then
range="$local_oid"
else
range="$remote_oid..$local_oid"
fi
# Check for WIP commit
commit=$(git rev-list -n 1 --grep '^WIP' "$range")
if test -n "$commit"
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0
```