「git diffがでない なぜ」
git status
をかけると、何故か大量の変更(modified)が発生してるけど、
diffをみてもなにも変更がないように見えるのでわからなくなった人向け。
gitのautocrlfの設定をどうして良いか困ってる人も以下を参考に。
TL;DR
おそらくファイルの権限と改行コード。
以下、関係者にwindows使用者が いない 場合のおすすめ。
なにをしているかわからない場合は、周りに確認を取ってから設定を変更のこと。
$ git config core.filemode=false # パーミッションの状態を無視
$ git config core.autocrlf=input # checkout時に変換せずcommit時にcrlf->lfする
$ git config core.safecrlf=true # ファイル内で改行コードが交じっている場合、安全に倒し変換しない
$ git config core.whitespace cr-at-eol # 差分で^Mが出ないように
毎リポジトリともこの設定でいいなら --global
オプション付きで上記を設定しておくことをおすすめ。
Winの場合、以下記事確認のうえ、プロジェクトにあわせてご検討されたし。
原因さがし
当方の環境
OS: Windows10 Home
- WSL(Ubuntu 18.04 LTS)
追記:
現状、職場が変わりArchLinuxを使用しているため参考程度。
当時(2018年)はWSL2がなかった時代で、周りでgitを知っている人間がおらず、個人でローカルのみで管理していた
また2024年現在マシニングセンタでアルミを削っているためプログラマですらないので以下は話半分で見ていただけると助かる。
状況
差分が大量に出た状況としては、
- WSL(Ubuntu)でいつも管理していたgitのブランチをキレイに見たかった
- SourceTreeでローカルのリポジトリ追加してみた
- なんか全ファイルが黄色になってステージング求めてきた。ヤバない?これ
- modified大量発生。
- 頭をかかえる
といった具合。
しかし git diff
でみると、
- 全ファイルのパーミッション 0755 -> 0644
- 行末に
^M
って大量にでる
という有様。
なんとなくだが、 Windows側のGitが悪い 気がしている。
以下ではそんなWindowsでうまいことやりくりするために考えたこと
状況の考察
全ファイルのパーミッション 0755 -> 0644
これは、WSL1上でつかってたものを Windows 側から触っちゃったため。
完全にこの時代のwslの挙動だったので今は起きなくなっている。
Linuxではrwxの権限を扱えるものの、Windowsでそのファイルを触った場合、
実行権限に当たるものがWindows(というかNTFSか)にうまく反映できず、実行権限を1..2の..ポカン! してしまうというバグだった。
^Mって大量にでてた
改行コード LF
-> CRLF
こいつについてはもう自明で、windowsの息のかかったGitはデフォで改行コードをCRLFに変換してしまうという話。
ただ厄介なのがcommit時にはLFに戻すので、Win使いしかいない場合はこのあたりの問題が表面化しない。
ただ最近はCRLFなんて使わんのでWin側で扱う時もLFでいいでしょ、と思っている。
Gitが複数ある
さらに厄介なのはWindowsや仮想マシンを使っている場合、Gitの実行ファイルが2つ以上ある可能性が高い。
ので、今どのGitが使われているのか、を意識する必要がある。
いくつgitがあるか調べてみた。
$ which git
/usr/bin/git
これはわかる。WSL(Ubuntu)のほうのgitだ。
いつもshellから使ってるのはこれ。
で、問題はGit Bash(Git for Windows)の方。
$ where git
C:\Program Files\Git\mingw64\bin\git.exe
C:\Program Files\Git\cmd\git.exe
$ which git
/mingw64/bin/git
えぇ…。
where
の下の方はPowerShell叩いたのと同義でGit for Windowsとしてインストールgit.exe、
which
はmingwのgit、ということですかね。
正味3つのgitがありました。まじか。
で、おそらくSourceTreeやGithub for Desktopなんかで使ってるgitは、
PowerShellと同じgit.exeだと思う。
対処
ひとまず、WSL側は冒頭と同じくすればいいが、
autocrlfについては割と意見が分かれるかと思う。
個人的にはLinuxかMacでしか編集しない && サーバはLinuxしか使わないので全部 LF
でいい。
CRLF
が紛れ込んでほしくないので core.autocrlf=input
を指定。
これはcheckout時にはそのまま取ってきて、commit時に CRLF
を抹殺し LF
にするというものである。
プロジェクトによっては CRLF
と LF
が混在とかいう、すでにやっちまった状況が発生している可能性もあるため、
この場合は input
にして LF
にした場合、副作用などないかが少し不安。
なので、プロジェクトの人と相談したり core.autocrlf=false
として改行コードをgitに触らせないのが板。
あとリポジトリ内どころかファイル内で混在とかいう地獄も想定されるが、現状を維持する最終手段として
core.safecrlf=true
が使えるので、安全に倒してつかうとよさそうである。
上記TL;DRで書いてある内容は雑な内容になるが、安全に行くとするとこうなるか
$ git config core.filemode=false # パーミッションの状態を無視
$ git config core.autocrlf=false # checkout, commit時に改行コード変換行わず
$ git config core.safecrlf=true # ファイル内で改行コードが交じっている場合、安全に倒し変換しない
$ git config core.whitespace cr-at-eol # 差分で^Mが出ないように
結論
いつも使っているgitを見極め、
globalで余計な差分を出さない設定にする。
あと、怖かったら各リポジトリの .git/config
でも逐一設定する。
もう改行コードはLFだけにしてくれ。という愚痴
ということでみなさんUbuntuでいいので開発にはLinux系つかいましょう。