Help us understand the problem. What is going on with this article?

[バッチ/git] バッチをgitに上げてそれを他の人がクローンすると、なんか動きませんけどと言われる(gitにコミット時の改行の扱いについて)

もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

やりたいこと

バッチを作成して、gitに上げて、他の人がそれをダウンロード(Cloneではなく)して使うとなんか文字化けしてうまく動かない、となってしまった。

ちょっと見ると、Gitにpushしてクローンしたときは、バッチファイル(に限らずテキストファイルすべて)の各行の改行コードはとくに変わらず元のままだが、zipでダウンロードすると、なぜか改行コードがunix形式(LF)になって帰ってくる。

そのバッチをダブルクリックして動かそうとしてもうまく動いてくれないので、「作ったときはうまくいったのに、他の人がダウンロードしたら動かない」ということなってしまっているっぽい。

対策

今回編み出した対策としては、下記を徹底すること。

  • 日本語を使うバッチファイルは、下記で保存する
    • SJIS
    • 改行コード=CR+LF
  • バッチファイルを使うときは、リポジトリをzipダウンロードして使わない。Cloneして使う。

後日追記で、最終的にはこうした、というのを書いた。このぺージの下の方を参照

そうする理由

2段階ある。

git側の理由

設定によるようだが、gitの標準設定では、
テキストファイルをコミットとpush、逆にチェックアウト(Clone)したときは、内部で

  1. コミット時に CRLF -> LF
  2. チェックアウト時に LF -> CRLF

がされている。

zipでダウンロードしたときは、その1番のほうだけ実施されて、2番の元に戻す処理の方が実施されないままダウンロードされるっぽく、LFになったままで帰ってきてしまう。

※gitの設定で、改行コードを変換しないように変えることができるっぽい。(こちら参照)
 が、gitの標準がこれをやる方なのであれば、個人的にあまり設定は変えたくないと思う。

コマンドプロンプト側の理由

  • 現状のWindowsのコマンドプロンプトでは、Unix形式の改行コード(LF)はうまく動いてくれない(LFで改行してると、改行として認識しないっぽい。日本語のある時だけ?)(こちら参照)
  • UTF8でBOMありにすると、BOMのせいでバッチの1行目がうまく実行されない。
  • 改行はCR+LFにしておかないと、コマンドプロンプトではうまく動かない(日本語なければうまくいくかも?)
  • また、utf-8でCRLF、BOMなしで問題なく動くかと思ったが、試したところうまく動かないケースがある。下記参照。

echo 日本語の文字列とやると、うまく動かなかった。

utf-8、BOMなし、CRLFでうまく動かないケース.bat
chcp 65001
echo あいうえお
echo あいうえお
echo かきくけこ
echo かきくけこ
echo 会い上御
echo 会い上御
pause

また、下の備考にあるように、ファイル名の日本語も文字化けする。

だから

バッチがうまくうごかなくなる。
個人的に、コメントに日本語を使うことや、echoで日本語を出力することは排除できないと思うので、上に書いた対策としたい。

備考

手元作業したフォルダ、cloneしてきたフォルダ、zipダウンロードしてきたフォルダを比較すると、こんな感じになった。(docとかsrcフォルダ、readme.mdは関係なし)
image.png

追記

改行コードはgitの設定によってそういう動きをしていた

ここまでで見てきたCR+LFLFになってしまう、などの動きは、gitの設定によるものと思われる。
→作業用PCにて、設定変更のためのコマンドgit config --global core.autocrlf falseを実行すると、改行コードが勝手にLFになるのは回避できることが分かった。なので、

  • core.autocrlf を falseにしておく
  • バッチをコミットするときにCRLFで保存しておく

を守れば、「改行がLFであるがためにバッチが動かない」は回避できる。

ただ、BOMがついていると、バッチの1行目をうまく実行できない件は回避できないので、最終的に下記のようになると思われる。

★最終的な対策

バッチファイルをgitにコミット/プッシュして使いたい場合、文字コード関連はこのようにしておけばよいと思われる。

  • git環境構築時
    • git config --global core.autocrlf falseを実行して、自動でCRLF変換されないようにする
  • コミット/プッシュ実施時
    • コメント以外に日本語を使わない
    • バッチファイルを下記の設定で保存する
      (バッチファイル自身にUTF-8を使いたい場合)
      • utf-8
      • BOMなし
      • CR+LF
    • バッチファイルを下記の設定で保存する
      (バッチファイル自身にSJISを使いたい場合)
      • SJIS
      • CR+LF

★最終的に得た教訓

  • バッチファイルは...

    • 改行コードがLFだと動かない。
    • 文字コードがutf-8だと動かない時がある。(詳しい条件は不明)
    • BOMありutf-8だと、1行目に化けた文字が入ってうまく動かない。
  • gitの環境は...

    • 適切に初期設定しておかないと、思わぬ動きをする。
    • 例えば、core.autocrlf がtrueだとコミット時に勝手に改行コードが変わる。(対策は上参照)
    • 関連メンバーで設定を同じにしておく必要アリ。

参考

バッチファイルを UTF-8 で書く
→バッチは改行=LFでは動かない、とある。
https://itpc.blog.fc2.com/blog-entry-193.html

コミット時に CRLF -> LF。チェックアウト時に LF -> CRLF。
→そういう変換が、自動でかかっているらしい。
https://qiita.com/shuhei/items/2da839de8803cb335f86

改行コード LF で日本語を含むバッチファイルの動作がおかしい件
→LF(+多分UTF8?)のときの動きを詳しく試しておられる。
https://miau.hatenablog.com/entry/20100929/1285768041

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away