web-dev-qa-db-ja.com

ファイルの更新時にデフォルトのumaskを変更します

Gitに問題があります。 GoogleとStackOverflowで解決策を探しましたが、何も役に立ちません。

問題は、gitが作業ディレクトリ内のファイルを更新するたびに(ブランチをチェックアウトするときやブランチをマージするときなど)、ファイルのアクセス許可が変更され、「グループに書き込み可能」フラグが追加されることです。また、グループ化に書き込み可能な場合、Apacheはファイルに対して「エラー500」を表示します。

例:ファイルindex.phpがあります。権限は「-rwxr-xr-x」です。現在の(アクティブな)ブランチはマスターです。このファイルは、ブランチ「develop」で変更されました。 「gitcheckoutdevelop」を実行すると、ファイルindex.phpに「-rwxrwxr-x」という権限が付与されます(グループへの書き込みが追加されます)。そして、私のサイトは機能しなくなります。 Apacheはphpファイルでこのフラグを許可していないため(理由はわかりませんが、これを変更することはできません)。

「gitcheckoutdevelop」を実行するたびに、「chmodg-windex.php」も実行する必要があります。 2つのコマンドを実行するのは好きではありません(そして、これを実行するのを忘れて、サイトが機能しないことがあります)。

この問題を解決するにはどうすればよいですか?これはumaskに関連したものだと思います。 Webで見つけたトリックをいくつか実行しましたが、何も機能しません。

ありがとう。

21
Roman Gelembjuk

ファイルをバイナリとして実行できるようにするのは危険です。とにかく私はumaskの問題を解決しました。私のpost-receiveスクリプトは次のようになります。

!/bin/sh
umask 002
GIT_WORK_TREE=/var/www/site git checkout -f

したがって、file permissionsを664に設定し、directory permissions775に設定します。これは、私にぴったりです。

P.S. gitユーザーの.profileファイルにumaskを設定しても効果がありません。理由がわかりません。理由がわかっている場合は、コメントアウトしてください。

9
zogby

簡単な答えは、このシェル関数を~/.profileに配置することです。以下に説明があります。

git(){(umask 0022; command git "$@")}

mask はプロセスのプロパティです。これは親プロセスから継承され、後で内部から変更できます。 umaskを変更するコマンドは、通常、umaskとも呼ばれます。

Gitには、umaskを設定するための構成オプションがなく、実行後にumaskを変更しません。 Gitのumaskを外部から設定し、親プロセス(通常はシェル)から継承させる必要があります。

うーん、あなたはgit以外のものがumaskを変更したという考えを嫌うようです。それでは、gitを実行するときに変更しましょう。

シェルが行を実行すると、その行の最初のWordを取得し、その名前の関数を見つけようとします。存在しない場合にのみ、PATHでその名前のコマンドを見つけようとします。上で書いた関数の名前はgitであるため、gitを直接呼び出すと、gitコマンドの代わりに実行されるようになりました。

この関数は、サブシェルを実行し、そのumaskを変更して、サブシェル内からgitコマンドを実行します。 Gitが作業を終了した後、サブシェルも終了し、元のShellインスタンスには元のumaskが残ります。

ただし、この関数は、それ自体をバイパスする方法も示しています。 command gitまたは/usr/bin/gitを介してgitを呼び出すと、関数は呼び出されません。ただし、適切な使用にはこれで十分です。

9
Palec

バックポートされたXenialバージョン4.xlinuxカーネルを使用してUbuntu14.04(Trusty)のNFS経由でマウントされたホームディレクトリへのリポジトリをチェックアウトするときに、この問題が発生しました。ローカルディレクトリへのGitクローンは問題ありませんでした。さらに奇妙なことに、2番目のUbuntu 14.04サーバーは、同じマウントされたディレクトリで同じ問題を示しませんでした。

何度も調べた後、gitがopen()システムコールを呼び出してオプションO_CREAT、O_WRONLY、O_EXCL、モードが0666の各ファイルを作成するstraceを使用しているのを見ることができましたが、次のsyscalはfstat()に対してでしたファイルとそれがモード0700であると私に言った。私の場合、問題はリポジトリ内の特定のファイルにのみ影響しました。 'git ls-index'はほとんどのファイルでモード0644を示していますが、正しく作成されているファイルとそうでないファイルがあります。クローンに対して間違った権限を持っていたのは常に同じファイルでしたが。

2つのシステム間でカーネルのバージョンに違いがあることに気づき、次のバグを発見しました: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1654288

カーネルを4.4.0-98(4.4.0-59から)にアップグレードすると、これが修正されました。バージョン3.xLinuxカーネルをまだ使用しているいくつかのホストを確認しましたが、問題はありませんでした。

4
JonathanDIT

チェックアウト後にフックを使用してファイルモードを変更すると、問題が発生した後で問題が修正されます。フックを実行すると、ファイルシステムにすでに不正なファイルモードがあります。チェックアウトとフックの実行の間にリクエストが到着した場合、サーバーは500エラーで応答します。しかし、とにかくこのソリューションに興味があるかもしれません。

あなたには必要だ post-checkoutフック実行chmod g-w必要なすべてのファイル。フックは.git/hooks/post-checkoutは実行可能である必要があり、現在のHEADを2番目のパラメーター(シェルでは$ 2)として取得します。フックは次のようになります。

#!/bin/bash
git ls-files -z --with-tree="$2" | xargs -0 chmod g-w --

フックはチェックアウトされたファイルのリストを取得しないため、これが可能な限り最良の実装である可能性があります。現在のHEADにあるすべてのファイルのモードを変更します。

1
Palec