注意
この記事は、core.autocrlf=trueの方が結果的に安全になる(一般的にはfalseにしろと言われているけど)、という主旨の記事ですが、既にfalseで運用がされている現場では、もちろん勝手にtrueにすれば混乱を生む可能性があります。
結局チーム全体で話し合って決めることですので、先走らないようご注意ください。
Windows環境でGitを使おうとすると改行コードの扱いに困る
Windows環境でGitを使い始める時に最初に悩むのが、改行コードの自動変換設定(autocrlf)です。
テキストファイルの改行コードは、Mac/Linux/Unixの世界では基本的にLFです。しかしWindowsではCR+LFとなっており、MacやLinuxで開発されたコードをWindowsで開くて編集すると、一部の行だけがCR+LFになっている改行コード混在ファイルが出来上がってしまったりして混乱します。
core.autocrlf設定とは
core.autocrlf 設定とは、下記のようなものです。
- true : コミット時はCRLF→LF変換、チェックアウト時はLF→CRLF変換してくれる
- input: コミット時はCRLF→LF変換、チェックアウト時は何も変換しない
- false: 何も変換しない
現状の設定は、以下のコマンドで確認できます。
git config core.autocrlf
グローバル設定は、以下のコマンドで確認できます。
git config --global core.autocrlf
Windows向けのGitセットアップ手順を説明したサイトでは、これを「false」にして余計な変換トラブルを避けましょう、ということが言われます。
しかし、個人的にはこれは多くの場合 trueが正解 ではないかと思っています。
前提として次のことがあります。
- Git for Windowsのインストーラは、規定値が true
- Visual Studio 2019 に同梱のGitのconfigも、true(但しこの設定より Git for Windowsが優先される)
- Visual Studio 2019 のGitの設定項目にはautocrlfの設定がない
上記のことから、Gitを始めてインストールする人の多くが、autocrlf = true の環境になっている可能性が考えられますし、Gitを使い始める人に 「falseにして!」と徹底するのもなかなか難しい 状況があります。
そこで改めて考えると、そもそも、なぜ CRLF⇔LF変換はまずいのでしょうか?
Windows環境で作業するのであれば、むしろうれしい事の方が多いのではないでしょうか。
いくつかのパターンで考えてみます。
Windows環境向けの製品の開発をしている場合
git config core.autocrlf true
最終的にWindows Serverで動作させる、またはWindows上で動作するexeやdllを作っているとします。
それらのソースコードは全部CRLFでしょう。
そういうものがGitのリポジトリ上でLFに変換されて保存されていたところで、チェックアウトすればCRLFになるのなら全く問題ないはずです。
それよりも、ある日 core.autocrlf = false に設定変更した一部の環境からコミットするとリポジトリに CRLF で保存されてしまい、リポジトリ上で改行コードがどんどん混在していく、といった状況の方が望ましくないでしょう。
「全てCRLFでファイル側を統一した上で、autocrlf = false にすれば、余計な変換が行われずシンプルだ」
と思う人もいるかと思いますし、それはその通りなのですが、実際には autocrlf = true 環境でコミットする人は必ず出ます。その場合、autocrlf = false の人は、ある日突然、改行コードがLFのファイルをチェックアウトして混乱することになるのです。
後述のdiffの問題が特に大きいです。
規定値の autocrlf = true 前提で運用する方が混乱が少ないでしょう。
.NET Core アプリを作っている場合
git config core.autocrlf true
.NET Coreアプリということは、最終的にLinux上で動作させる可能性もありますよね。
なので、できればファイルの文字コードはLFで統一されている方が良いでしょう。
開発環境がMac/LinuxとWindowsで混在している可能性もあります。
しかし作業者の中にはWindows環境のエディタで改行コードの設定をせず、CRLFの改行の入ったファイルを作る人も出てきます。
そういう人がいた場合、もし autocrlf = false になっていると、リポジトリ上もチェックアウト後の作業フォルダも、改行コードがどんどん混在していくことになります。
これがもしautocrlf = true ならば「Windows環境ではCRLFで作業する」を一貫しつつ、Linux環境ではautocrlf=falseにすることで、全ファイルをLFで取得することができます。
よく「autocrlf=trueにしていたせいで、CRLFファイルをLinux環境に配置しちゃったよ」みたいな話を聞いたりもするのですが、それはむしろデプロイ環境の問題でしょう。Windows上で作業しているファイルを直接Linuxにデプロイするからそういうことになるわけで、そういうことをしたいなら、文字コード変換を挟むなどするのが本筋だと思います。
ASP.NET Coreアプリとはいえ、テスト環境はWindowsだったりする場合もあり、開発環境ではCRLFで統一されていた方が何かと便利だったりします。
この場合も autocrlf = true がベターでしょう。
Linux環境専用のアプリを諸事情でWindow環境で作っている
git config core.autocrlf false
そういう場合もあるでしょう。その場合、開発環境自体をLFで統一した方が何かと便利だと思います。
エディタの文字コードもLFに設定し、CRLFを許さないという姿勢で臨むべきでしょう。
その場合は(当たり前ですが)、autocrlf = false で運用した方が良いと思います。
ただ、その場合でも、どうしても使い慣れたエディタがCRLFにしてしまう、というような場合などは、その人だけが autocrlf = true で運用するのはありだと思います。その場合でも、コミット時にはLFになってリポジトリに保存されているわけですから、問題ありません。この環境から直接実行環境にファイルを配置するような場合については、もちろん十分な注意が必要です。
そもそも、Gitリポジトリ上で改行コードが混在する事自体大問題
Gitリポジトリ上でLFだったファイルを、autocrlf = false の環境で、誰かがCRLFに変換してコミットしたとします。
そうすると、改行コード以外は何も変わっていないにも関わらず、それは「全行変更された」とみなされ、diffに表示されます。
悪名高い「^M」が行末についたdiffを見たことがあるのなら、まさにそのような問題が起こっている証拠です。
autocrlf = true であれば、CRLFに変換したファイルをコミットしても、コミット前にLFに変換されますから、そもそも変更として認識されず、安全です。
Gitリポジトリ上では必ずLFで統一されるようにすべきです。
その上で、開発環境で改行コードがCRLFになっていて欲しい、ということであれば、autocrlf = true を使うのです。
一部のテキストファイルだけはautocrlfの対象外としたい場合
autocrlf=trueで運用しているが、一部のファイルはLFのままコミット/チェックアウトをしたい、という場合もあるかもしれません。
そのような時は、.gitattribute に設定を記載します。
* text=auto
*.txt text
*.vcproj text eol=crlf
*.sh text eol=lf
*.jpg -text
上から順に、
- テキストファイルとして判断されるものは、autocrlf対応する
- .txt はテキストファイルとして判断する
- .vcproj は 改行コードをCRLFで一貫する。
- .sh は 改行コードをLFで一貫する。
- .jpg は autocrlf=false 扱い(つまり改行変換処理を行わない)
という内容になるようです。
詳しくはこちらの記事をどうぞ。
まとめ
いかがでしょうか。これまで、「Windows環境ではautocrlf = false にせよ」と言われてきた方も、もしこれを読んで「なるほど」と思われたのであれば、これからは autocrlf = true で運用することを検討しても良いかと思います。
autocrlf = false は、チーム全員が改行コードに注意を払っているのが前提です。つまり、人に依存します。
autocrlf = true は、チームが改行コードに注意を払わずとも、リポジトリは確実にLFに統一されます。つまり、人に依存しません。
この件について「それは認識が間違っている」「こんな問題がある」というご意見がありましたら私も意識を変えなければならないので、ご指摘頂ければ幸いです。
参考