以前、HSP3(Hot Soup Processor)製のアプリをGitHubで公開しようとしたときにハマった話です。いつものようにコミットしてgit pushしたら、GitHubからダウンロードした配布物が何故かエラーを吐いて起動しない。
SnapCrab_Error_2021-10-19_3-56-52_No-00
HSPエラー13は画像が見つからない場合に発生するエラー。しかし、画像ファイルが欠けているわけではない。
しかも、OneDriveでのファイル共有など、配布にGitHubを介されければ動く…
なぜだ…なぜだー

問題のブツ

今回GitHubで公開する際にハマったのは、こちらで公開しているWorld Timepieceという世界時計アプリ。
HSP3製で、背景に表示する画像のファイル名をテキストファイルに保存し、起動時にそれを読み込むことで背景画像を取得して表示しています。
worldtimepiece

原因は改行コード

git commit前後のテキストファイルをバイナリエディタで見比べてみたら、改行コードが書き換わっていた。
E40Ry24UUAYRD6m

調べてみると、Gitは既定でWindowsからgit commitする際に全てのテキストファイルの改行コードをCR+LFからLFに自動変換する仕様らしい。改行コードというのはファイルの改行を示すための文字コードですが、WindowsではCR+LFが、MacやLinuxなどのUNIX系OSではLFが標準で採用されています。つまり、GitはWindowsからcommit&pushするテキストファイルの改行コードをUNIXに合わせて自動変換しているということです。
一方、HSP3で読み込むファイルはCR+LFが標準仕様。よって、起動時に背景画像のファイル名をテキストファイルから取得しようとした際に、テキストファイルをCR+LFのつもりで読み込んだらLFに変換されていて上手く読み込めない、というのが原因と考えられます。
hsp3crlf_image

Windows版Gitでは、git pullするとテキストファイルをCR+LFに自動で戻してくれます。しかし、GitHub上でリリースしたものはGitHub上でそのままzip形式に圧縮され、通常はブラウザから直接ダウンロードされますから、当然ファイルの改行コードはLFのままダウンロードされます。

まとめると、

  • Git for WindowsはUNIX系OSと互換性を持たせるためgit commit時にCR+LFLFに自動変換する
  • Git for Windowsはgit pull時にLFCR+LFに自動変換する
  • しかし、GitHubでリリースしたものはLFのまま公開される
    • ソフトウェアによっては読み込むファイルの改行コードの違いでエラーが発生(HSP3の場合も該当)

…正直、Windowsでしか開発しないのに余計なお世話だ!ってなりません?(そもそもGitがLinux用に作られたという話はさておき)
ここからは、Gitによる自動変換を無効化する方法を紹介します。

対処法:Gitに改行コードの自動変換をさせない

まずはコマンドラインツール(MINGW32やMSYS2など)を開き、対象となるローカルリポジトリへ移動(既にローカルリポジトリ上にいる場合は不要)。

$ cd {ローカルリポジトリのファイルパス}

次に以下のコマンドを実行。

$ git config --local core.autocrlf false

これだけでOKです。何をしているかというと、リポジトリ内での改行コードの自動変換を無効化しています。
あとは普通にgit commitしてgit pushすれば、CR+LFのままGitHubにpushされます。これでGitHubでリリースしても大丈夫。

なお、この設定は該当のリポジトリにだけ適用されます。全リポジトリに適用したい場合は--local--globalに置き換えて実行しますが要注意(理由は後述)。

注意すべき点

当然、これによって改行コードは自動変換されなくなりますから、特に複数のOS、複数の開発者間で開発している際は要注意です。CR+LFLFのファイルが混在してしまうとビルドエラー等が多発し他の共同開発者に迷惑をかけてしまいます。
よって、HSP3製アプリなどWindowsでしか開発・実行しないリポジトリにのみローカルで設定を適用することをおすすめします。

まとめ

テキストファイルの読み書きが必要なHSP3アプリをGitHubで公開する時は、Gitによって改行コードがLFに自動変換されていないか気を付けよう。HSP3は基本的にCR+LFにしか対応していません。セーブデータを伴うゲームアプリなど、これが原因でデータが読み込めなくなる、なんてケースも考えられます。