「何も変更してないのに、git statusで大量のファイルが変更されてる!」
「git diffを見たら、パーミッションだけが変わってる…」
こんな経験、ありませんか?特にWindowsとLinuxを行き来したり、WSL(Windows Subsystem for Linux)を使っている人にとっては、よくあるトラブルなんです。
実は、Gitにはファイルの実行権限の変更を「差分」として検出する機能があります。でも、開発環境によってはこの機能が邪魔になることも。この記事では、Gitで権限変更を無視する方法を分かりやすく解説します。
「本当は内容を変えてないのに、権限だけで差分扱いされる」という悩みを、コマンド1つで解決できますよ。
Gitが追跡する「権限」とは?

まず、Gitがどんな権限を追跡しているのか理解しておきましょう。
Gitが記録する3つのモード
Gitは実は、3種類のファイルモードだけを記録しています:
100644(通常ファイル)
- 所有者:読み書き可能
- 他のユーザー:読み取り専用
- 実行権限なし
100755(実行可能ファイル)
- 所有者:読み書き・実行が可能
- 他のユーザー:読み取り・実行が可能
- シェルスクリプトなどに使用
120000(シンボリックリンク)
- ファイルへのリンク(ショートカットのようなもの)
つまり、Gitは「実行できるかどうか」だけを気にしているんですね。所有者やグループなどの細かい情報は記録されません。
問題が起きる仕組み
LinuxやMacでは、ファイルシステムが権限情報を持っています。でも、Windowsは違うんです。
例えば:
- Linuxで作った
644のファイルをGitにコミット - Windowsでクローンすると、全ファイルが
755扱いになってしまう - 「権限が変わった!」とGitが検出してしまう
こうして、何も編集していないのに大量の差分が発生するわけです。
権限変更を無視する必要があるケース
実際にどんな場面で権限の無視が必要になるのか、具体例を見てみましょう。
ケース1:Windows + WSLの環境
Windows上にあるファイルをWSL(Ubuntu等)から操作すると、パーミッションが自動的に変わってしまいます。
# WSLから確認すると...
$ git status
modified: .gitignore
modified: README.md
modified: script.sh
(実際には何も変更していない)
$ git diff
old mode 100644
new mode 100755
すべてのファイルで権限が変わっているように見えますが、実際は内容は同じなんです。
ケース2:複数のOSで開発
チームメンバーがWindowsとMacとLinuxをそれぞれ使っている場合、権限の差分でコンフリクト(衝突)が発生することがあります。
$ git pull
error: Your local changes to the following files would be overwritten by merge:
README.md
config.json
Aborting.
内容は変わっていないのに、権限だけが違うためにマージできない状態になるんですね。
ケース3:chmod -R 777をやってしまった
「動かないから、とりあえず全部に実行権限つけちゃえ!」というのは危険です。でも、一度やってしまうと…
$ git status
modified: file1.txt
modified: file2.txt
modified: file3.txt
...(数百ファイル)
画像ファイルやテキストファイルまで実行可能になってしまい、すべてが差分として検出されます。
core.fileModeで権限を無視する方法
それでは、実際に権限変更を無視する設定をしていきましょう。
基本コマンド:特定のリポジトリで無視
まず、今作業しているリポジトリだけで権限を無視する場合はこちら:
git config core.fileMode false
たったこれだけです!
コマンドの効果を確認
設定が反映されたか確認してみましょう:
# 設定を確認
$ git config core.fileMode
false
# 差分を確認
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
さっきまで大量にあった差分が消えましたね。
グローバル設定:すべてのリポジトリで無視
「今後作る全てのリポジトリで権限を無視したい」という場合は、--globalオプションを付けます:
git config --global core.fileMode false
これで、今後クローンしたり作成したりするすべてのリポジトリに適用されます。
注意:
既存のリポジトリには自動で適用されません。既存のリポジトリで使いたい場合は、それぞれのリポジトリで個別に設定する必要があります。
設定内容を確認する方法
「ちゃんと設定できたかな?」という時は、以下のコマンドで確認できます。
現在のリポジトリの設定を確認
git config core.fileMode
出力がfalseなら、権限を無視する設定になっています。
すべての設定を一覧表示
git config --list | grep filemode
これで、ローカル設定とグローバル設定の両方を確認できますよ。
core.filemode=false
設定ファイルを直接確認
設定は、実際には以下のファイルに保存されています:
リポジトリごとの設定
.git/config
グローバル設定
~/.gitconfig(Linux/Mac)
C:\Users\ユーザー名\.gitconfig(Windows)
テキストエディタで開くと、こんな感じで記載されています:
[core]
filemode = false
実際の作業例:設定前と設定後の比較

実際にどのように動作が変わるのか、具体例で見てみましょう。
設定前の状態
# ファイルの権限を変更
$ chmod 755 script.sh
# Gitで確認すると...
$ git status
On branch main
Changes not staged for commit:
modified: script.sh
$ git diff
diff --git a/script.sh b/script.sh
old mode 100644
new mode 100755
権限変更が「差分」として検出されています。
設定後の状態
# 権限無視の設定を有効化
$ git config core.fileMode false
# 同じように権限を変更
$ chmod 755 script.sh
# Gitで確認すると...
$ git status
On branch main
nothing to commit, working tree clean
$ git diff
(何も表示されない)
権限変更が無視され、差分として認識されなくなりました!
サブモジュールがある場合の設定
プロジェクトにGitサブモジュールが含まれている場合は、それぞれのサブモジュールにも個別に設定が必要です。
各サブモジュールで設定
# メインリポジトリで設定
git config core.fileMode false
# サブモジュール1で設定
cd submodules/module1
git config core.fileMode false
cd ../..
# サブモジュール2で設定
cd submodules/module2
git config core.fileMode false
cd ../..
面倒ですが、サブモジュールごとに.git/configが独立しているため、個別設定が必要なんです。
一括設定スクリプト
複数のサブモジュールがある場合は、シェルスクリプトで一括設定すると便利です:
#!/bin/bash
# すべてのサブモジュールでfileMode=falseに設定
git config core.fileMode false
for dir in submodules/*; do
if [ -d "$dir/.git" ]; then
cd "$dir"
git config core.fileMode false
cd ../..
echo "設定完了: $dir"
fi
done
注意点とデメリット
便利な機能ですが、使用にあたってはいくつか注意点があります。
デメリット1:実行権限の管理ができなくなる
core.fileMode=falseにすると、意図的な実行権限の変更も追跡されなくなります。
例えば:
- シェルスクリプトに実行権限を付けたい
- セキュリティ上、実行権限を外したい
こういった正当な権限変更も、Gitが無視してしまうんです。
デメリット2:本番環境との不整合
開発環境でfileMode=falseにしていると、本番環境にデプロイした時に問題が起きることがあります。
# 開発環境では実行できたのに...
$ ./deploy.sh
bash: ./deploy.sh: Permission denied
本番環境では権限がないため実行できない、というトラブルが発生する可能性があります。
デメリット3:チーム開発での混乱
チームメンバーによって設定が違うと、混乱を招きます。
- Aさん:
fileMode=true(デフォルト) - Bさん:
fileMode=false
この状態だと、Bさんの環境では問題なくても、Aさんの環境では権限の差分が大量に出てしまいます。
推奨される使い方
それでは、どのように使うのがベストなのでしょうか?
推奨1:プロジェクト単位で設定
グローバル設定ではなく、プロジェクトごとに判断して設定しましょう。
# グローバルではなく、ローカルで設定
git config core.fileMode false
こうすることで、本当に必要なプロジェクトだけで無視できます。
推奨2:READMEに記載
チームで開発している場合は、プロジェクトのREADME.mdに設定方法を書いておきましょう。
## 開発環境のセットアップ
このプロジェクトでは、OSによる権限の差異を防ぐため、
以下のコマンドを実行してください:
\`\`\`bash
git config core.fileMode false
\`\`\`
これで、新しいメンバーが参加した時もスムーズです。
推奨3:実行権限が必要なファイルは明示的に設定
fileMode=falseにしても、実行権限が必要なファイルはgit update-indexで明示的に設定できます:
# 特定のファイルだけ実行権限を設定
git update-index --chmod=+x deploy.sh
# コミット
git commit -m "Add execute permission to deploy.sh"
これなら、必要な権限だけをGitで管理できますね。
よくあるトラブルと解決方法
実際に遭遇しやすいトラブルとその解決策をまとめました。
トラブル1:設定したのに差分が消えない
症状:
$ git config core.fileMode false
$ git status
modified: script.sh
(まだ差分が出る)
原因:
既にステージングエリア(インデックス)に変更が追加されている状態です。
解決方法:
# ステージングエリアをリセット
git reset HEAD
# または、変更を破棄
git checkout -- .
トラブル2:Windowsでchmodが効かない
症状:
$ chmod 644 file.txt
$ ls -l file.txt
-rwxrwxrwx 1 user user 0 Dec 11 10:00 file.txt
(権限が変わらない)
原因:
WindowsのファイルシステムはLinuxのような詳細な権限を持っていません。
解決方法:
これは正常な動作です。core.fileMode=falseに設定することで、この違いを気にせずに済むようになります。
トラブル3:pullできない(権限の衝突)
症状:
$ git pull
error: Your local changes would be overwritten by merge.
原因:
リモートとローカルで権限が違うため、マージできない状態です。
解決方法:
# 一時的に変更を退避
git stash
# pullする
git pull
# core.fileModeを設定
git config core.fileMode false
# 退避した変更を戻す(これで権限の差異は無視される)
git stash pop
設定を元に戻す方法
「やっぱり権限も追跡したい」という場合は、設定を元に戻せます。
ローカル設定を元に戻す
git config core.fileMode true
グローバル設定を元に戻す
git config --global core.fileMode true
設定を完全に削除
# ローカル設定を削除
git config --unset core.fileMode
# グローバル設定を削除
git config --global --unset core.fileMode
設定を削除すると、Gitのデフォルト動作(権限を追跡する)に戻ります。
代替手段:.gitattributesを使う
core.fileMode以外にも、権限を制御する方法があります。
.gitattributesファイルで制御
プロジェクトのルートに.gitattributesファイルを作成して、ファイルごとに細かく制御できます:
# すべての.shファイルに実行権限を保証
*.sh text eol=lf
# 特定のファイルだけ追跡
deploy.sh binary
この方法なら、チームメンバー全員で同じ設定を共有できますよ。
まとめ
Gitで権限変更を無視する方法、しっかり理解できましたか?最後に重要なポイントをおさらいしましょう。
権限を無視する基本コマンド:
# 現在のリポジトリで無視
git config core.fileMode false
# すべてのリポジトリで無視(グローバル)
git config --global core.fileMode false
設定の確認:
git config core.fileMode
こんな時に使おう:
- Windows + WSLで開発している
- チームで複数のOSを使っている
- 権限の差分が大量に出て困っている
注意点:
- 実行権限の管理ができなくなる
- 本番環境との不整合に注意
- チームで設定を統一する
おすすめの使い方:
- プロジェクト単位で設定
- READMEに設定方法を記載
- 必要なファイルは
git update-indexで個別設定
この設定を使えば、「何も変更してないのに差分が出る」というストレスから解放されますよ。ただし、セキュリティ上重要な権限管理が必要なプロジェクトでは、慎重に判断してくださいね。
それでは、快適なGitライフをお楽しみください!


コメント