GitHub で Download ZIP した時に改行コードが LF になってしまう件(原因は core.autocrlf)

Git が使えない方向けに、Download ZIP リンクを貼り付けて「ここから Zip ファイルをダウンロードしてください」という形で配布する方法があるが、このやり方には注意点がある。

Zip 展開後のソース中の改行コードが LF になってしまうことがある。

なので バッチファイルなど LF だと動かないファイル を配布する場合は注意が必要。私は Commainder というバッチファイル製のリマインダーを配布しているが、これが見事に LF まみれになっていた。

原因は何?

抑えておくべきポイントは二つある。

  • (1) Download ZIP はリポジトリ内のファイルをそのまま zip にする
    • つまり リポジトリ内ファイルが LF なら、zip に同梱されるファイルも LF
  • (2) git config の core.autocrlf 次第で、ファイルの文字コードが変わる

つまり (2) の設定のせいで、CRLF でコミットしたつもりでも実際リポジトリ内では LF になっている のが原因。

解決方法は?

二つある。

方法1: .gitattributes ファイルをつくる

.gitattributes というファイルをつくっておくと、指定ファイルの属性を変更できる。属性として「改行コード」にも対応している。

たとえば以下はバッチファイルの文字コードを CRLF にする例。

*.bat  text eol=crlf

方法2: core.autocrlf を false にする

ローカルリポジトリに対して core.autocrlf を false にした上でコミットする。

$ git config --local core.autocrlf false

(参考) core.autocrlf について

core.autocrlf の値次第では「リポジトリにコミットする時」と「リポジトリからチェックアウトする時」の 2 つのタイミングで ファイルの文字コードが変化する

core.autocrlf は元々、

  • Git「文字コードは基本的に LF でしょ」
  • Windows「うちは CRLF デフォなんだけど……」

という齟齬に対処するために生まれたオプションである。

core.autocrlf では以下の選択肢を用意した。

  • autocrlf=false(何も変換しない)
  • autocrlf=true(コミット時は LF にして、チェックアウト時は CRLF にする。そっちで使う時は CRLF になってるんだから問題ないでしょ?うちもデフォの LF で保存できるし、Win-Win だよね)
  • autocrlf=input(コミット時のみ LF にする。チェックアウト時は CRLF にしないから、LF でコミットしてたファイルは LF のまま扱えるよ。trueよりも融通きくでしょ?)

つまり Git はあくまで LF でのみ保存することを譲らない というスタンスのもと、CRLF 派の Windows が CRLF でも扱えるよう融通をきかせる(コミット時とチェックアウト時にこっそり変換をかける)のである。

(参考) core.safecrlf について

今回調査中にちらほら見かけたのでついでにまとめとく。

複数の改行コードを含む(CRLFとLFを両方含む)ファイルを扱う時、autocrlf だけだとそれら改行コードが (本来は両方含んでいるにもかかわず) LF のみ or CRLF のみ になってしまう。これを防ぐための設定が safecrlf。

具体的には、複数の改行コードを含むファイルがあった時に autocrlf の変換が行われようとすると、警告を出したり操作を中止したりする。

  • safecrlf=false(何もしない)
  • safecrlf=true(混在時に当該操作を中止する)
  • safecrlf=warn(混在時に警告を出すが中止はしない)

参考リンク