macOSでgit commitがPermission deniedになる原因と根本解決方法
macOS環境で開発をしていて、 git commit
を実行したところ、突然以下のようなエラーメッセージが表示されました。
$ git commit
error: could not create temporary file: Permission denied
fatal: failed to write commit object
このエラーは、Gitがコミットメッセージなどを書き込むための一時ファイルを作成しようとした際に、権限がなく失敗したことを示しています。
実は、この問題については以前、macOSでgit commitがPermission deniedになる原因とワークアラウンドな解決策という記事にしましたが、今回はその続編です。根本的な原因を特定し、恒久的な対策を施すことができたので、その方法を皆さんにご紹介します。
調査を進めた結果、原因は環境変数 TMPDIR
にありました。
何らかの操作(おそらく sudo
を使ったコマンドの実行)がきっかけで、Terminalセッション、ひいてはGUIセッション全体で使われる TMPDIR
が、一般ユーザーではなくrootユーザーの一時ディレクトリを指すように変わってしまっていたのです。
TMPDIR
は、多くのアプリケーションが一時ファイルを保存するために参照する重要な環境変数です。このパスの所有者がrootになっていると、一般ユーザー権限で実行されているGitは書き込みができず、Permission denied
エラーを引き起こします。
解決策は、この TMPDIR
を現在のログインユーザー用の正しいパスに設定し直すことです。手順は非常にシンプルです。
まず、現在のGUIセッション全体で使われる環境変数を設定し直します。以下のコマンドをTerminalで実行してください。
launchctl setenv TMPDIR "$(getconf DARWIN_USER_TEMP_DIR)"
このコマンドが何をしているかを分解してみましょう。
getconf DARWIN_USER_TEMP_DIR
: macOSの標準機能で、現在のユーザーが使用すべき一時ディレクトリの正しいパスを取得します。launchctl setenv <変数名> <値>
: macOSのGUIアプリケーションを含む、より広いスコープで環境変数を設定するコマンドです。つまり、この一行で「GUIセッション全体の TMPDIR
環境変数を、現在のユーザー用の正しいパスに再設定する」という処理を行っています。
launchctl
で設定した環境変数を現在開いているTerminalアプリに反映させるため、一度Terminalを完全に終了(Cmd + Q
)し、再度起動します。
再起動後、念のため以下のコマンドで TMPDIR
が正しいパスになっているか確認してみると良いでしょう。
echo $TMPDIR
おそらく /var/folders/...
といったユーザー固有のパスが表示されるはずです。
この状態で git commit
を実行すれば、今度こそエラーが出ることなく、正常にコミットが完了するはずです。
git commit
での Permission denied
エラーは、TMPDIR
環境変数が意図せず変更されてしまったことが原因であるケースがあります。特に sudo
を使った操作の後に発生した場合は、この可能性を疑ってみると良いでしょう。
今回の解決策は、その場しのぎではなく根本原因にアプローチするものです。同様の問題に悩まされている方の助けになれば幸いです。
以上、macOSでgit commitがPermission deniedになる問題を根本解決した、現場からお送りしました。