Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Why Coding Agents Turn a CRLF File Into a Whole-File Diff, and What Codex 0.162 Changed

2026年10月19日に「Dev.to」が公開したITニュース「Why Coding Agents Turn a CRLF File Into a Whole-File Diff, and What Codex 0.162 Changed」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AIがファイルを編集する際、WindowsとUnixの改行コード(CRLF/LF)を勝手に変え、Gitで全行が変更されたように見えてしまう問題があった。Codex 0.162では改善したが、.gitattributesで改行コードのルールを設定し、AIによる誤った差分を防ぐことが重要だ。

ITニュース解説

AIコーディングエージェントが開発現場で活用されるようになったことで、私たちは新しい効率性を手に入れた。しかし、その一方で、これまで経験しなかったような予期せぬ問題に直面することもある。その一つが、AIエージェントにほんのわずかな修正を依頼しただけなのに、Gitのプルリクエストを見ると、まるでファイル全体が一度削除され、その後にすべて新しく追加されたかのように表示される、という現象だ。開発者仲間から「何を書き直したの?」と聞かれるたびに、実際には目に見える内容の変更はほとんどないのに、どう答えたらいいか困ってしまうだろう。

この一見奇妙な問題の核心は、「改行コード」という、ファイルには直接表示されない特殊な文字の違いにある。コンピュータのOSによって、テキストファイルが行の終わりを示す方法が異なるのだ。Windows環境では「CRLF」(キャリッジリターンとラインフィード、\r\nと表記される)という2つの文字が使われるのが一般的だ。これに対し、Unix、Linux、macOSなどの環境では、「LF」(ラインフィード、\nと表記される)という1つの文字が使われるのが一般的である。このCRLFとLFの「見えない1バイト」の違いが、Gitの差分検出を混乱させる主な原因となっている。

AIエージェントが、CRLF形式で書かれた既存のファイルを読み込み、その内容を編集して、LF形式でファイルを保存し直してしまうことがある。Gitはファイルの変更を検出する際、バイト単位で比較を行うため、各行の終端にあったCRLFがLFに変わるだけで、その行全体が「変更された」と判断してしまうのだ。その結果、ファイルの内容自体はほとんど変わっていないにもかかわらず、Gitはすべての行が削除され、新しい行として追加されたと報告し、プルリクエストの表示ではファイル全体が削除(赤色)と追加(緑色)で埋め尽くされてしまう。

この問題をより深く理解するためには、Gitがどのようにファイルを管理し、差分を比較するのかを知る必要がある。Gitは、コミットされた時点のファイル(BLOBと呼ぶ)、ステージングエリア(インデックスと呼ぶ)、そして現在作業しているファイル(作業ツリーと呼ぶ)という3つの状態を扱う。git diffコマンドは、主に作業ツリーにあるファイルとインデックスにあるファイルを比較する。改行コードの自動変換は、この作業ツリーとインデックスの間で発生することがあるが、これはGitがファイルをテキストファイルとして認識している場合に限られる。

Gitには、改行コードの扱いを自動で調整するための設定がいくつか用意されている。最も基本的なのはcore.autocrlfという設定で、これをtrueに設定すると、Windowsではコミット時にCRLFをLFに変換し、チェックアウト時にはLFをCRLFに戻す。LinuxやmacOSではinputに設定することで、コミット時にCRLFをLFに変換するが、チェックアウト時は何もしない。しかし、このグローバル設定だけでは、すべてのケースをカバーできるわけではない。

より詳細な制御には、リポジトリ内に.gitattributesファイルを作成して利用する方法がある。このファイルを使うことで、特定のファイルの種類(例えば、拡張子*.batのファイルなど)に対して、改行コードの扱いを細かく指定できる。例えば、*.bat text eol=crlfと記述すれば、.batファイルは常にCRLF形式でチェックアウトされるように強制できる。text=autoという設定もあり、Gitが自動的にファイルの改行コードのタイプを判断しようと試みるが、ここには落とし穴がある。もし、ファイルが.gitattributesで何も設定されるよりも前にCRLF形式でコミットされていた場合、text=autoが設定されていても、Gitはそのファイルの改行コード変換を自動では行わないのだ。AIエージェントが問題を発生させるのは、まさにこの「Gitの改行コードルールが適用されていないCRLFファイル」に対して編集を行った場合が多い。

この改行コード問題は、実際に簡単な手順で再現できる。macOS、Linux、またはGit Bash環境で、以下のコマンドを実行してみよう。まず、git init -q crlf-demo && cd crlf-demoで新しいGitリポジトリを作成し、git config core.autocrlf falseで改行コードの自動変換をオフにする。次に、printf 'one\r\ntwo\r\nthree\r\n' > run.batと入力して、CRLF形式のrun.batファイルを作成し、git add run.bat && git commit -qm "CRLF file"でコミットする。最後に、printf 'one\ntwo\nTHREE\n' > run.batと入力し、ファイルの一部の単語を「THREE」に変更しつつ、全ての改行コードをLF形式で書き換えて上書きする。この状態でgit diff --statを実行すると、実際に変更されたのは1行の1単語だけにもかかわらず、3行が削除され、3行が追加されたと表示されるはずだ。これは、AIエージェントが改行コードを変換してファイルを書き換えた場合と同じ状況を再現している。

Gitには、このような問題を診断するための便利なツールも用意されている。git ls-files --eol run.batコマンドを実行すると、指定したファイルのインデックス(i/)、作業ツリー(w/)、そしてそのファイルに適用されているGit属性(attr/)における改行コードの情報を確認できる。上記の再現手順で作成したrun.batに対してこのコマンドを実行すると、i/crlf(インデックスではCRLF)、w/lf(作業ツリーではLF)、そしてattr/は空欄と表示されるだろう。これは、「CRLF形式でコミットされたファイルが、作業ディレクトリではLF形式になっているが、Gitにどう対処すべきか指示するルールがない」という状況を明確に示している。

また、git diff --ignore-cr-at-eol run.batコマンドは、差分を比較する際に、行末にあるキャリッジリターン(CR)を無視する。もしこのフラグを付けてgit diffを実行した際に、大量に表示されていた差分が一瞬にして実際の変更箇所だけに縮小された場合、その差分の原因は改行コードの違いだったと判断できる。

AIコーディングエージェントの開発元も、この問題の重要性を認識し、対応を進めている。例えば、OpenAIのCodex CLIはバージョン0.162で、既存のCRLFファイルを更新する際に、明示的な指定がなくても既存の改行コードを保持するようになった。AnthropicのClaude Codeも過去のバージョンで同様の修正を適用しているが、ユーザーからの報告を見る限りでは、まだ完全に解決されていないケースも存在するようだ。AIエージェントの「Edit」や「Write」ツールが、意図せず改行コードを変換してしまったり、あるいは二重に付与してしまったりする問題が引き続き報告されている。

この改行コード問題を恒久的に解決するための最も確実な方法は、プロジェクトのGitリポジトリ内で改行コードに関する明確なポリシーを確立することだ。まず、一時的にファイルを手動で修正する際には、perl -pi -e 's/\r?\n/\r\n/' run.batのようなPerlのコマンドを使って、全てのLF改行をCRLFに変換することができる。これにより、ファイルは正しい状態に戻り、git diffは正しく1単語の変更だけを表示するようになる。

しかし、これはあくまで一時的な対処に過ぎない。永続的な解決策は、リポジトリのルートディレクトリに.gitattributesファイルを追加することだ。このファイルを使って、プロジェクト内の全てのテキストファイルの改行コードをLFに正規化し、必要に応じてWindows環境でのみCRLFとしてチェックアウトされるように設定できる。例えば、以下のような記述が考えられる。

* text=auto
*.bat text eol=crlf
*.cmd text eol=crlf
*.sln text eol=crlf
*.png binary

この設定では、まず全てのファイルをテキストとして自動判別させ、.batや.cmd、.slnのようなWindows固有のファイルはチェックアウト時にCRLF形式になるように強制し、.pngのようなバイナリファイルは改行コード変換の対象外とする。

.gitattributesファイルを追加しても、既にコミット済みのファイルの改行コードは自動では変換されないため、これらの新しいルールを既存ファイルに適用するには、一度クリーンな作業ツリーからgit add --renormalize .コマンドを実行し、その変更をコミットする必要がある。これにより、Gitのインデックス内の改行コードはLFに統一され、Windows環境でファイルがチェックアウトされる際には、.gitattributesのルールに従ってCRLFに変換されるようになる。

さらに、継続的インテグレーション(CI/CD)のパイプラインに! git ls-files --eol | grep 'i/crlf'のようなチェックを追加することで、Gitのインデックス内にCRLF形式のファイルが誤って混入していないかを確認し、もし発見されればビルドを失敗させる、といった運用も可能になる。これにより、誤った改行コードのコミットを未然に防ぎ、プロジェクト全体のファイルの整合性を高いレベルで保つことができる。

AIコーディングツールを活用した開発ワークフローにおいては、このような問題の発生を早期に検知する仕組みも非常に重要となる。例えば、Hermes IDEのようなツールは、AIエージェントが行った各「ターン」での変更内容を細かく記録し、ファイル数や行の追加・削除数を表示する。これにより、AIがたった1行の変更を意図したのに、ファイル全体が変更されたように見える不審なターンを容易に特定できる。このような変更の可視化は、問題のある変更を早期に発見し、修正する上で非常に役立つだろう。

この改行コードの問題は、異なるシステムやツールが、暗黙のうちに異なるファイル形式を期待している場合に発生する典型的な例である。Gitはどちらの改行コードが「正しい」と自動的に判断できないため、開発者が介入して明確なポリシーを設定する必要がある。特にAIコーディングエージェントのような新しいツールを導入する際には、このような「見えない違い」が引き起こす予期せぬ挙動に注意し、適切なGit設定と診断ツールを積極的に活用することが、スムーズで効率的な開発ワークフローを維持するために不可欠となる。

関連コンテンツ

関連IT用語

関連ITニュース