LoginSignup
18
13

Gitくん「全部変更されとるやで」ワイ「!? 一箇所も変更しとらんが!」

Last updated at Posted at 2019-04-11

「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年現在マシニングセンタでアルミを削っているためプログラマですらないので以下は話半分で見ていただけると助かる。

状況

差分が大量に出た状況としては、

  1. WSL(Ubuntu)でいつも管理していたgitのブランチをキレイに見たかった
  2. SourceTreeでローカルのリポジトリ追加してみた
  3. なんか全ファイルが黄色になってステージング求めてきた。ヤバない?これ
  4. modified大量発生。
  5. 頭をかかえる

といった具合。
しかし 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があるか調べてみた。

WSLで実行
$ which git
/usr/bin/git

これはわかる。WSL(Ubuntu)のほうのgitだ。
いつもshellから使ってるのはこれ。

で、問題はGit Bash(Git for Windows)の方。

GitBashで実行
$ 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 にするというものである。

プロジェクトによっては CRLFLF が混在とかいう、すでにやっちまった状況が発生している可能性もあるため、
この場合は 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系つかいましょう。

参考

Git - git-config Documentation

18
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13