posix file modeについて
git は Posix 環境で使われる、 Posix 用のシンプルなファイルパーミッションの設定がを保存します。
このパーミッションが file mode と呼ばれています。
gradlew
など、実行ファイルを git で保存する際にこのファイルパーミッションの設定を誤るとそのファイルを実行するために、実行権限を与え、working tree に差分を作らなくてはいけなくなります。
そのため git を扱う際にはこのファイルパーミッションを理解し、適切に付与しましょう。
Posixにおける代表的なファイルのメタデータたち
まず Posix File Mode を理解するために必要なファイルのメタデータの話をします。
Posix において Posix File Mode に関連するファイルのメタデータは、以下の2つがあります。
- owner user
- owner group
owner user
名前の通り、ファイルの所有者とされるユーザーを指定します。
owner group
名前の通り、ファイルの所有者とされるユーザーグループを指定します。
直感に反しているかもしれませんが、 owner user が owner group に所属している必要はありません。
Posix File Mode の機能
Posix File Mode のフラグは user, group, other という3種類の対象と、 read, write, execute という3種類の権限の組み合わせによる、9つのフラグと、実行時に使われる suid, guid, sticky bit の3つのフラグの計12bitで構成されています。
なお、 git で保存されるのは user, group, other の read, write, execute の合計 9 bitのみです。
もし自身が owner user だったら user の、もし自身が owner group に所属していたら group の、その他の場合は other の権限を使います。
read 権限
この権限は文字の通り、ファイルを読むための権限です。この権限がないとファイルを読むことができません。
ディレクトリの場合はディレクトリ内のファイルの一覧の取得権限になります。
Posixの面白いところの一つでもあるのですが、この権限がなくても書き込み権限があればファイルに書き込むことができるので、ファイルの上書きや末尾への追記はこの権限がなくてもできます。
一般的に新規ファイルの作成時には、この権限を user, group, other のすべての人に与えてることが多いです。
write 権限
この権限は文字の通り、ファイルに書き込むための権限です。前述の通り書き込むだけであれば読み込み権限はいりません。
ディレクトリの場合はディレクトリ内のファイルの作成/削除の取得権限になります。
一般的に新規ファイルの作成時には、この権限をユーザーにのみ与えてることが多いです。
execute 権限
この権限はディレクトリとファイルで効果が違います。
ディレクトリに対してはそのディレクトリ内のファイルへのアクセスを許可するかのフラグになります。
ディレクトリの読み込み権限はディレクトリ内のファイルの一覧へのアクセス権限を示すので、ディレクトリへのアクセス権限がなくても実行権があればディレクトリ内のファイルへのアクセスができます。
ファイルに対してはファイルを実行ファイルとして(コマンドとして)実行可能かを示します。
例にもれずこの権限は読み込み権限と独立しているため、ファイルを読めないけど実行は可能なファイルなども作れます。
一般的に新規ファイルの作成時には、ディレクトリの場合はこの権限を user, group, other のすべての人に与えてることが、ファイルの場合は一切与えないことが多いです。
suid
ファイルに対して使用した場合、実行時の user を owner user に変えます。
sudo
コマンドのような、常に root[1] 特権が必要なコマンドで使われます。
ディレクトリに対しては意味がないフラグです。
guid
ファイルに対して使用した場合、実行時の group を owner group に変えます。
ディレクトリに対して使用した場合、ファイルをそのディレクトリ内で作成する際に owner group を作成者の group ではなく、ディレクトリの group にします。
sticky bit
ファイルに付けた場合、古く、高速化のために、実行終了後もメモリに保持しておくためにつけるフラグでしたが、最近では必要がないため Linux
等では実装されていません。
ディレクトリに付けた場合、そのディレクトリ直下のファイルの削除や名前変更がそのファイルの owner user のみしかできないようになります。
Posix ではファイルの削除や名前変更は追加と同様にディレクトリの変更なので、 /tmp
など誰でもファイルを追加できるディレクトリでは第三者にディレクトリを削除されてしまう可能性があります。
sticky bitを /tmp
につけることで /tmp
内のファイルを第三者に削除される可能性を減らせ[2]ます。
Posix File Mode の表記
Posix File Mode を示すのには一般的な表記は複数あります。
1つ目は rwxrwxrwx
表記です。
この表記では、3文字ごとに user, group, other の read, write, execute フラグを示し、権限がないところは -
に置き換えます。
suid, guid は user, group の execute フラグのところを s
(executeフラグがないときは S
) に置き換えます。
同様に sticky bit は other の execute フラグのところを t
(executeフラグがないときは T
) に置き換えます。
例えば rw-r--r--
は、 owner user は読み書き、 その他の人は読みだけ可能な file mode を示します。
2つ目は、8進数表記です。
read, write, execute のフラグを 1bit づつとみると、 3bit であり、8進数で一桁で表記できます。
そのため 644
のように、 user, group, other をそれぞれ8進数一桁で表記し、3桁の8進数で表します。
例えば 755
は rwxr-xr-x
を示します。
suid, guid, sticky bit は user, group, other の前の一桁に追加します。
例えば 4644
は rwsr-xr-x
を示します。
Windows 上の git での扱い
Windows では Posix File Mode を保存できないので、 add するとデフォルトで 0644
になります。
以下のコマンドで index tree 上の File Mode を変更します。
<差分>
の形式は chmod
で調べてください。 +x
みたいなやつです。
git update-index --add --chmod=<差分> <file>
# 例: gradlew
git update-index --add --chmod=+x gradlew
Discussion