技術にゃんこの混ぜご飯

関東某所でITエンジニア生活を送るブログ主がチラ裏メモを放り込む場所

【Git】masterブランチへのコミットを禁止する

masterへのコミット禁止ぃ~!(゚Д゚#)

カテゴリ:Git
jym1975によるPixabayからの画像 (木登りするサバトラ猫

経緯

(´・ω・`)「野良えもーん、masterにコミットしちゃったよー」
(,,=ω=)「あー、必要な変更?不要?なら git りせっ」
(´・ω・`)「良く分からないから直してー」

・・・数日後。

(´・ω・`)「野良えもーん」
(,,=ω=)「・・・またぁ?」

うっかりブランチを切り忘れて、コミット前に気が付けば良いんですが、コミットまでしてしまうと元に戻せないらしい。

リモートはしっかり設定してあるから、プッシュしてしまう心配はないものの、毎回呼んでいてはお互いに作業に差し支えますよね。

自分が扱ってる技術なんだから覚えてよと言うのは簡単ですが、考えてみれば熟練のコミッターでさえ極限状態に陥ればやらかしそうなもの。

そもそも特定のブランチにコミットできなければいい訳ですから、pre-commit で何とかできないかと思ったのが始まりです。

pre-commit の中身

#!/bin/sh

if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

exec 1>&2

branch=$(git rev-parse --abbrev-ref "$against")

if test "$branch" = "master"
then
    cat <<\EOF
masterへのコミット禁止ぃ~!(゚Д゚#)
EOF
    exit 1
fi
C:\Project\.git\hooks\pre-commit

『#!/bin/shって?』とか『pre-commitとはなんぞや』とか『4b825(ryて何だよ』とかは、本題ではないので尺の都合でやりません。

git rev-parse

Pick out and massage parameters

『massage』という単語にはマッサージ以外にも、事実や数字を良く見えるように改ざんするような意味や、単純に好ましい状態に操作・変換するような意味もあるようです。

『git rev-parse』はgitに登録されている情報をあれこれして、特定の情報を選んだり整形したりできるコマンドのようです。

この辺りドキュメントの『massage』という表現が分かりにくいのもありますが、rev-parse 自体が色々やること詰め込み過ぎてる感が。

実際にコマンドを叩いてみた方、早いと思います。まあ、コマンドを打って出てきたデータがどこから来てるかは、きちんと把握していないといけないですけども。

--abbrev-ref

$ git checkout develop
Switched to branch 'develop'

$ git rev-parse --abbrev-ref HEAD
develop
コンソール

abbrev は略称、ref は参照。HEADは現在使用しているブランチの先頭を指すので、ここでは現在のブランチ名を取ってくることになります。

git rev-parse --abbrev-ref HEAD 自体は『現在のブランチ 取得』で検索すると出てくるので、知っている方も多いと思います。エイリアスに設定している方もいるのではないでしょうか。

ちなみに他の出力オプション(Options for Output)には以下のようなものがあります。

$ git rev-parse --short HEAD
32b2857
$ git rev-parse --not HEAD
^32b2857accea4031c0857488220405457460b4f2
$ git rev-parse --symbolic HEAD
HEAD
$ git rev-parse --symbolic-full-name HEAD
refs/heads/develop
コンソール

--symbolic で返ってくる値には注意。

test "$branch" = "master"

これはGitの話ではなくシェルスクリプトの話です。単純に文字列を比較してるだけです。

今回は master でしたが、文字列を変更すれば別のブランチへのコミットを禁止することもできます。

また複数指定したい場合は -o を使えば可能です。が、流石に3つ以上になったら配列定義にした方使い勝手は良さそうですね。

実行結果

$ git commit -m "masterにコミットしてやる!"
masterへのコミット禁止ぃ~!(゚Д゚#)
コンソール(PowerShell 7.0.0)

このくらいだと可愛いですね。

$ git commit -m "masterにコミットしてやる!"

    ∧∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
   (,,゚Д゚)< masterへのコミット禁止ぃ~!
   ⊂  ⊃ \_______________
  ~|  |
    し`J

$ git commit -m "masterにコミットしてやる!"

         /\
        ../  ./|
      ∴\/./
     _, ,_゚∵ |/
   (ノ゚Д゚)ノ
  /  /

$ git commit -m "masterにコミットしてやる!"

.  ゚。
 コポ ゚
   ゚。゚
    。゚
    ゚。゚コポ
    。゚
_(┐「ε:)_  ここどこ?

 _人人人人人_
 > master <
  ̄Y^Y^Y^Y^Y^ ̄
コンソール(PowerShell 7.0.0)

色々変えてみました。Git Bashそのままだとフォントの関係で、AAがずれますね。

Sourcetree だと以下のように表示されます。

SourceTreeのエラー出力(masterへのコミット禁止ぃ~!)
SourceTree Version 3.3.8

色々な環境のことを考えると顔文字くらいが無難そうです。自分だけが使うなら煽りAAとかの方、愛着は湧くと思います。

あと何もコミットするものがなくても上記が表示されるので、間違ってはいないんですが少し気持ちが悪いです。この辺りは改良しないとですね。