1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Git上で、特定のファイルへパーミッションを自動設定する

1
Posted at

Gitにはファイルのパーミッションを管理する機能がある…のはいいのですが、Windows上から扱っていると確認も設定も面倒なものです。自動化できるパターンのものは自動化したいものです。

背景事情

  • Gitコミットから連動してサーバデプロイを行う環境を構築している
  • この際に、.some_hooks/以下に置いた、パーミッション755のスクリプトファイルを自動実行する
  • なお、.some_hooks/に644のファイルを置いているとデプロイ時にエラーとなる

実際に、毎回パーミッションを正しく設定するのは面倒だし、忘れてデプロイエラーとなる事故をやらかしたことも何度かありました。

また、簡易的に作ったものなので、ファイル名にスペースや改行文字が入る、過激な環境での動作は想定していません。

Git Hooksとは

Gitには、Git Hooksといって、「特定の操作をしたときにスクリプトを実行する」機能があります。今回はコミットするタイミングで手を入れたいので、pre-commitが適当です。

なお、Git HooksはGitの管理フォルダのhooksサブフォルダの中に置きますが、Hooks自体はGit管理されないことには要注意です。

書いたコード

コードにすれば意外とシンプルでした。

# !/bin/bash

git diff --name-only --diff-filter=d --cached | grep '^\.some_hooks/' | xargs git update-index --add --chmod=+x

まず、最初のgit diff --cachedでステージングされた変更との差分を抽出します。--diff-filter=dは「削除された変更は除外」ということで、これを除外しないと削除したファイルのパーミッションを変えてステージングしようとしてしまい、エラーとなります。--name-onlyは文字通り、ファイル名だけ抽出するオプションです。これで、「ステージングされた、新規作成(の可能性がある)ファイル1の、改行区切りのリスト」を取れました。

次にこのリストをgrepに流して、「.some_hooks/で始まるもの」、すなわち「.some_hooks/以下にあるもの」だけを抽出します。

最後にこのリストをxargsで引数リストに変換して、Gitのパーミッション変更コマンドへ流し込めば、ミッションコンプリートです。

感想

細かいコマンドをつないで1つの動作を作る、Unix哲学の奥深さをまた1つ感じました。

外部リンク

  1. 中身を書き換えただけのファイルも取得されてしまいますが、ファイル移動など細かなパターンまで逐一指定するのが煩雑になるのと、そしてあとでパーミッション書き換えの操作を行っても特に問題ないので放置しています。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?