[[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 ```