13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

もう迷わない .gitattributes で改行コードを統一

Last updated at Posted at 2021-06-28

きっかけ

Gitで差分を見るとき...

diff --git a/README.md b/README.md
index 21d2221..28086a1 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
 Apple
+Banana^M
+

というように、差分の行末に ^M が付与されて鬱陶しい場合がある。
Windowsの改行コードがCRLFなのに対し、
Linuxの改行コードはLFになっているため、
GitはCRLFのCR部分を余計なものと見なし、こういった形で表示される。
設定で非表示にすることもできるのだが、
コミットの際に誤って改行コードを混在させないためにデフォルト設定のままにした方が良いと思う。
ただ、改行コードが混在していないかどうかを目視でチェックするのはあまりにも面倒くさい...
改行コードの混在をシステム的に防ぐ方法は無いのだろうか?

世の中の人たちはこの問題にどう対処しているのか

Windowsで開発を行い、改行コードの混在問題に直面する機会が多いであろうMicrosoftのリポジトリを見てみる。
https://github.com/microsoft/vscode-dev-containers

.gitattributes
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.gif binary
*.jpeg binary
*.png binary
*.gz binary
*.jar binary

この例だと、基本的にはLFに寄せて、Windows固有のcmdファイルとbatファイルだけ例外的にCRLFにしている。

また、改行コードの統一について言及しているページを探してみたところ、MicrosoftによるVSCodeのドキュメントがヒット。
Visual Studio Code Remote Development Troubleshooting Tips and Tricks
該当部分をGoogle先生に翻訳してもらうと、

コンテナー内のGit行終了の問題の解決(多くの変更されたファイルが発生します)
WindowsとLinuxは異なるデフォルトの行末を使用するため、Gitは、行末以外に違いがない多数の変更されたファイルを報告する場合があります。これを防ぐために、.gitattributesファイルを使用して、またはWindows側でグローバルに行末変換を無効にすることができます。
通常 .gitattributes、リポジトリ内のファイルを追加または変更することが、この問題を解決するための最も信頼できる方法です。このファイルをソース管理にコミットすると、他の人を助け、必要に応じてリポジトリごとに動作を変えることができます。たとえば、以下を .gitattributes ファイルにリポジトリのルートに追加すると、CRLFを必要とするWindowsバッチファイルを除いて、すべてが強制的にLFになります。

.gitattributes
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf

やはり基本はLFで、Windows固有のファイルだけCRLFにしている。

他のリポジトリも見てみると、
https://github.com/microsoft/vscode

.gitattributes
* text=auto

LICENSE.txt eol=crlf
ThirdPartyNotices.txt eol=crlf

*.bat eol=crlf
*.cmd eol=crlf
*.ps1 eol=lf
*.sh eol=lf
*.rtf -text

あれ?今度はちょっと違う
まあ * text=auto によってリポジトリでLFに変換されるので、結局内部的にはLFになるんだけども
個人的には eol=lf でLFで統一する方がシンプルで分かりやすいんじゃないかと思った。
ところで、ps1ファイルが eol=lf と指定されているのがちょっと意外だった。
そういえば、先程の例でもps1ファイルはCRLFに変換されていなかったので、どうやらps1ファイルの改行コードはLFらしい。
本題からは少し話が逸れるが、binaryファイルを明示的に指定する必要はあるんだろうか?
そうしていないリポジトリもたくさんあるのを考えると、わざわざ明示的に指定する必要はないような気もする。
ユーザーの側がバイナリファイルを全て記載するのは手間がかかりすぎるし、そこらへんはGit側で判断して上手いことやってくれているんじゃないだろうか?分からないけど

結論

基本的にLFで統一して、cmdファイルとbatファイルだけCRLFにする

.gitattributes
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
13
11
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
13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?