スキップしてメイン コンテンツに移動

【Day 33】CRLF/LF改行コード問題と .gitattributes 完全定義

Day 33 アイキャッチ
▲ 【Day 33】CRLF/LF改行コード問題と .gitattributes 完全定義
👨‍🏫
皆さん、こんにちは! 本講座の専任講師です。
前回のDay 32では、直前ブランチへ瞬時に復帰する git switch - や神エイリアス設定、PowerShell環境でのブランチ状態常時可視化を学びました。
そして本日のDay 33からは、待望の「第7部: Windows & C# (.NET) 固有の落とし穴完全制覇」へと突入します!
第7部の開幕を飾るテーマは、すべてのWindows / C#エンジニアを恐怖に陥れてきた最大の罠――【CRLF/LF改行コード問題と .gitattributes 完全定義】です!
「たった1行のコードを修正してプルリクエストを出しただけなのに、ファイル全1000行が差分になってしまいレビューを怒られた…」
「Windows端末とLinux CI環境でビルド結果やスクリプト実行結果が食い違う…」
「ネットの記事に従って core.autocrlf = true にしたのに、チームメンバーによって改行コードがバラバラになって大混乱…」
このようなトラブルは、WindowsとUnix系OSの歴史的な改行コード差異と、Gitの改行変換メカニズムを正しく制御できていないことが原因です。
本講義では、SVN時代の svn:eol-style の統制力を凌駕する現代Gitの決定版――「.gitattributes」の書き方と、既存の汚染リポジトリを一瞬で浄化する一括正規化手順を完全解説します!

① 導入・本日の達成目標

C#や.NETの開発現場は、Visual Studioが動くWindows端末が主流ですが、現代のビルドパイプライン(GitHub Actions、Azure DevOps、GitLab CI)やコンテナ環境(Docker)はLinux環境(LF)で動作することが標準となっています。
この「Windowsクライアント(CRLF)× Linux CI/サーバー(LF)」のハイブリッド構成こそが、改行コード事故が最も多発する温床です。
開発者個人のPC設定に頼るのではなく、リポジトリ自体に厳格なルールを埋め込むことで、チーム全員が何もしなくても100%安全な環境を構築しましょう。

🎯 本日のゴール
  • CRLF( )とLF( )の構造的差異と、「全行差分事故」が発生するメカニズムを理解する
  • 従来のSVN(svn:eol-style)とGitにおける改行コード管理の思想の違いを把握する
  • なぜ core.autocrlf の個人設定だけに依存してはいけないのか、その致命的弱点を学ぶ
  • C#プロジェクト(.cs, .sln, .csproj, バイナリ)に最適化された .gitattributes の完全設定テンプレートをマスターする
  • すでにCRLF/LFが混在して汚染されたリポジトリを git add --renormalize . で一撃正規化する手順を習得する

② 【図解】改行コードの食い違いが生む「全行差分」の悲劇

まずは、なぜ改行コードの違いだけでチーム開発が崩壊するのか、その全貌を図解で確認しましょう。

改行コードの食い違いが生む「全行差分」の悲劇
▲ 【図解①】改行コードの食い違いが生む「全行差分」の悲劇

テキストファイルの各行末には、画面上には表示されない特殊な制御コード(改行コード)が記録されています。

OS / 環境 改行コード バイト表現 特徴・主な使われ方
Windows CRLF 0x0D 0x0A (\r\n) タイプライター時代の復帰(CR)+改行(LF)を継承。Visual Studioの伝統。
Linux / macOS LF 0x0A (\n) Unix系OSの標準。Git内部リポジトリやCI環境、Dockerの標準。

Gitはファイルをテキストとしてではなく「バイト列の完全一致(SHA-1/SHA-256ハッシュ)」で厳密に追跡します。
そのため、ソースコードの見た目上の文字列が1文字も変わっていなくても、行末が 0x0A から 0x0D 0x0A に変わっただけで、Gitは「その行のデータが完全に書き換えられた」と判定します。
この結果、以下のような深刻な実害が発生します:

  • コードレビューの崩壊: プルリクエストの差分が数十ファイル・数千行の全行差分で埋め尽くされ、本当に変更した本質的な1行を見失う。
  • マージコンフリクトの多発: 別の開発者が並行作業していた場合、全行が衝突対象となり、手動解消が絶望的な巨大競合に発展する。
  • git blame(履歴追跡)の汚染: 「誰が・いつ・何の目的でその行を書いたか」という歴史的記録が、改行コードを一括変換した犯人のコミットで上書きされ、過去の調査が不可能になる。

③ 【図解】個人設定 core.autocrlf に頼る危険な落とし穴

「Gitには自動で改行を変換してくれる core.autocrlf があるから大丈夫では?」と思われがちですが、ここに最大の罠があります。

個人設定 core.autocrlf に頼る危険な落とし穴
▲ 【図解②】個人設定 core.autocrlf に頼る危険な落とし穴

Gitには、各開発者のローカル環境で設定する git config --global core.autocrlf という機能が存在します。

⚠️ core.autocrlf の3つの値と挙動
  • core.autocrlf = true (Windows推奨とされてきた設定): チェックアウト時にLF→CRLF変換、コミット時にCRLF→LF変換。
  • core.autocrlf = input (Mac/Linux推奨): チェックアウト時は何もしない、コミット時のみCRLF→LF変換。
  • core.autocrlf = false (変換なし): チェックアウト時もコミット時も一切変換せず、そのまま保持。

一見便利に見えますが、これには「開発者全員が正しい設定を確実にセットしていること」が前提という致命的な弱点があります。
新入社員やパートナー企業の開発者がPCを初期セットアップした際、core.autocrlf の設定を忘れたり、VS CodeやGit GUIがデフォルトの false でコミットしてしまった瞬間、リポジトリにCRLFのファイルがそのまま混入します。
SVNではサーバー側設定やリポジトリ設定(svn:eol-style = native)で集中管理できていましたが、Gitの core.autocrlf はローカル端末ごとの個人設定であるため、チーム全体の統一を強制できません。

④ 【図解】C#現場のための .gitattributes 決定版設定

この問題を根本から、かつ100%確実に解決する決定打が「.gitattributes」です!

C#現場のための .gitattributes 決定版設定
▲ 【図解③】C#現場のための .gitattributes 決定版設定

.gitattributes は、リポジトリのルートディレクトリに配置するGit設定ファイルです。
このファイルの最大の特徴は、「リポジトリ自体にコミットされるため、クローンした全開発者およびCI環境に100%強制適用される」という点です。開発者個人の core.autocrlf 設定は完全に無視され、.gitattributes のルールが最優先されます。

📋 C#/.NET 現場の黄金テンプレート(そのままコピーして使えます)

# -----------------------------------------------------------------------------
# 1. リポジトリ全体のデフォルト設定(テキストはLFで統一、改行自動検出)
# -----------------------------------------------------------------------------
* text=auto eol=lf

# -----------------------------------------------------------------------------
# 2. C# / .NET ソースコードおよびマークアップ
# -----------------------------------------------------------------------------
*.cs           text diff=csharp eol=lf
*.csx          text diff=csharp eol=lf
*.razor        text diff=html eol=lf
*.xaml         text eol=lf
*.xml          text eol=lf
*.json         text eol=lf
*.md           text eol=lf
*.yml          text eol=lf
*.yaml         text eol=lf

# -----------------------------------------------------------------------------
# 3. Visual Studio / Windows 特有ファイル(CRLF固定が必須の例外)
# -----------------------------------------------------------------------------
*.sln          text eol=crlf
*.bat          text eol=crlf
*.cmd          text eol=crlf
*.ps1          text eol=crlf

# -----------------------------------------------------------------------------
# 4. プロジェクトファイル(新形式SDKスタイルはLFで完全安定)
# -----------------------------------------------------------------------------
*.csproj       text eol=lf
*.fsproj       text eol=lf
*.props        text eol=lf
*.targets      text eol=lf

# -----------------------------------------------------------------------------
# 5. バイナリファイル(改行コードの自動変換を絶対禁止)
# -----------------------------------------------------------------------------
*.png          binary
*.jpg          binary
*.jpeg         binary
*.gif          binary
*.ico          binary
*.dll          binary
*.exe          binary
*.pdb          binary
*.nupkg        binary
*.zip          binary
💡 なぜ *.sln だけは CRLF 固定なのか?

Visual Studioのソリューションファイル(.sln)は、古いパーサー仕様の名残により、行末が LF になっているとVisual Studioで保存した瞬間に自動的に CRLF へ書き戻されてしまいます。
その結果、ソリューションを開いて保存するだけで不要な改行差分が毎回発生してしまいます。そのため、*.sln やWindows専用の *.bat は eol=crlf と明示的に指定するのがC#現場のベストプラクティスです。

⑤ 【図解】汚染されたリポジトリを救う「改行コード一括正規化」3ステップ

「すでにリポジトリ内にCRLFとLFが混在してしまっている既存プロジェクト」はどうすればよいでしょうか?
Gitには、既存リポジトリの改行コードを .gitattributes に従って一括クリーニングする公式コマンドが用意されています。

汚染されたリポジトリを救う「改行コード一括正規化」3ステップ
▲ 【図解④】汚染されたリポジトリを救う「改行コード一括正規化」3ステップ

🛠️ 正規化の完全実行手順(たったの3ステップ)

ステップ①: .gitattributes をリポジトリ直下に配置する

上記テンプレートの内容で .gitattributes を作成し、リポジトリのルートに保存します。

ステップ②: git add --renormalize . を実行する

未コミットの変更がないクリーンな状態で、ターミナルで以下のコマンドを実行します:

git add --renormalize .

※ Gitがリポジトリ内の全ファイルを走査し、.gitattributes のルールに基づいてインデックス内部の改行コードを一括再計算・ステージングします。

ステップ③: 正規化コミットを作成してプッシュする

他の機能修正と絶対に混ぜず、「改行コード正規化専用の単独コミット」として記録します:

git commit -m "style: .gitattributes を導入し、全ファイルの改行コードを一括正規化"
git push origin main

⑥ 専任講師の総括・まとめ

📌 本日の重要ポイント
  1. 改行コードの差異(CRLF vs LF)はバイナリレベルの破壊: 見た目が同じでもGitにとっては「全行変更」となり、レビュー不能・巨大コンフリクトの原因になる。
  2. core.autocrlf 個人設定は信用しない: チーム全員が正しく設定することを期待するのは不可能。リポジトリにコミットされる設定ファイルで強制する。
  3. .gitattributes は現代Gitの絶対的防壁: * text=auto eol=lf をベースに、C#ソースは diff=csharp、Visual Studio用の .sln は eol=crlf、画像やDLLは binary で完全固定せよ。
  4. 既存の混在プロジェクトは git add --renormalize . で浄化: 他の変更と混ぜず、単独コミットとして一括正規化することで、将来の全行差分事故を恒久的に撲滅できる。
次回予告【Day 34】:
第7部・第2弾のテーマは「Visual Studio / VS Code 固有ファイル(.vs, bin, obj)の完全除外(.gitignore極意)」です!
知らず知らずのうちにキャッシュや巨大バイナリをGitにコミットしてリポジトリが肥大化する悲劇を防ぐ、プロの完全除外テクニックを伝授します。お楽しみに!

コメント

このブログの人気の投稿

【Perfume】Perfume 3rd Tour 「JPN」さいたまスーパーアリーナに行って参りました~

Perfume 3rd Tour 「JPN」1月28日、29日の2daysで参戦して参りました。 ファンクラブ会員の選考抽選会に28日、29日の両日で申し込んでいたんですが、両方とも当選していたという嬉しい誤算。 仕事だぁ、なんだかんだと紆余曲折ありまして28日の参戦は危ぶまれていたのですが、なんとかかんとか28日は40分遅刻しながらも参戦、29日はフル参戦する事が出来ました(∩´∀`)∩

Perfume、2025年末で“コールドスリープ(活動休止)”へ──東京ドーム2daysの記録と、公式・各界・ファンの声

  1) 公式発表・基本情報 活動休止(コールドスリープ)を正式発表 2025年9月21日、公式サイト「 Perfumeより 」で、2026年から一度コールドスリープに入ると発表。再始動の意思(“新しいPerfume”として戻る)も明記。 Perfume Official Site 今後の運用告知(配信・上映など) 同21日付の「 今後のPerfumeに関して 」で、9/23(火・祝)東京ドーム公演の LIVESHIP全世界生配信 および 全国ディレイビューイング 決定を案内。特設サイトも併記。 Perfume Official Site +1 公式グッズ **「Perfume Calendar 2026」**発売決定(B2壁掛け/表紙+2カ月1枚×6枚+ポスター)。テーマは“フルーツ”。 Perfume Official Site 2) 東京ドーム2days(9/22・23)要点 公演タイトル: ZO/Z5 Anniversary “ネビュラロマンス” Episode TOKYO DOME 。日程・開場/開演・会場・物販等の実務情報は特設で公開。 Perfume Official Site 9/23公演を世界配信(LIVESHIP) /ディレイビューイング実施。 Perfume Official Site 海外向け報道(英語)も「 indefinite hiatus 」として広く配信。 The Times of India 国内英字メディアも速報。 朝日新聞 3) 現地レポ( メリ爺 )から見える空気 あなたの現地記録(9/24公開)を、ファクトと現場情景の両面で反映: 両日参戦 。22日は アリーナ 、23日は 1階席から俯瞰 。前日の発表を受け、開演前のザワつき→MC後に“いつもの一体感”へ。開演は22日 18:45 頃。オープニングは**P³ツアー東京ドーム(2020/2)**と同趣向で“回収”の演出。 メリ爺のゲーム万歳 MC所感 :解散ではなく前向きな休止で不安を和らげる内容。 かしゆか の涙、 のっち の気丈さ、 あ〜ちゃん の思い出語り──3人の結束と「 また戻る 」約束が強く刻まれた。 メリ爺のゲーム万歳 体感時間 : “3時間弱”級のボリューム ながら“過去一...

ニンテンドースイッチでオンラインゲームを遊ぶには?

モンスターハンターライズが発売になって、家族でモンハン楽しみたい人が増えたみたいですね。 某ブログの検索キーワードを調べると、モンハンを家族でやるにはどうしたらいいのか?を調べている人が沢山いるのがわかります。 ※これでも一部  家族で協力するにはSwitch2台、ソフトも2つ購入する必要があります。 1台のスイッチでは遊べませんし、ソフト1つでも遊べません。 でも、1台のスイッチで別々アカウントがあれば交代で遊ぶこともできますよ。セーブデータもしっかり分かれます。 Switchのオンラインゲームを家族で遊ぶ方法については以下の記事にまとめてますのでよろしければ参考にしてみてくださいね。 家族でモンスターハンターライズDL版のオンラインプレーを楽しむ方法