🎧 Listen to this article: English
🌍 Read this in your language: हिंदी · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · ଓଡ଼ିଆ · 日本語 · 中文
コードでのマージコンフリクトでさえ十分に厄介です。それが画像ファイルで発生した場合、ほとんどの人は思考停止してしまいます。画像用の「差分ビュー」はなく、GitHubにあるいつものブラウザ内で修正するボタンは単に存在しません。この記事では、まさにその実際のケースについて順を追って説明します。何が機能しなくて、何が機能したのか。
今日、2026年8月29日現在、より多くの小規模チームがGitを通じてコンテンツ重視のWebサイトを運営しており、非技術者がデスクトップアプリを通じてテキストや画像の変更をプッシュしているため、これを理解する価値があります。分かりやすい言葉を使うコンテンツ編集者、バイナリファイル、実際のデプロイパイプラインが混在する環境こそ、この問題がまさに現れる場所なのです。
設定:2つのブランチ、1つの共有画像
プロジェクトでは、シンプルな2つのブランチのワークフローを使用しています。 staging は日々の作業が行われる場所です。コンテンツ編集者がそこへ自由に変更をプッシュし、プレビューサイトに自動的にデプロイされます。 main は実際のライブサイトであり、レビュー済みのPull Requestが staging からマージされたときにのみ更新されます。
チームはまた、最近サイトの画像をWebPに変換しました。これは、同じ視覚品質でPNGやJPGよりもはるかに小さいモダンなフォーマットです。今ではすべての画像がペアとして存在しています。オリジナルの .png、そして一致する .webpであり、それらはHTMLの <picture> 要素で結び付けられているため、WebP対応ブラウザは自動的に小さなファイルを取得し、他のすべてのブラウザはオリジナルにフォールバックします。
そして、2つの異なるブランチでほぼ同時に2つのことが起こりました。誰かが小さな直接編集を加えた製品スクリーンショットの場所は mainでした。これにより通常のレビューフローがバイパスされました。一方でコンテンツ編集者が個別に、まったく同じスクリーンショットの完全に新しいバージョンをアップロードした場所は stagingでした。両方の編集が同じファイルパスに触れました。どちら側も相手のことを知りませんでした。
GitHubのWebサイトがこれを修正できなかった理由
コンテンツ編集者が、 staging の更新を次のブランチ: mainに取り込むためのPull Requestを開いたとき、GitHubはすぐにそれにフラグを立てました。「このブランチには、解決しなければならないコンフリクトがあります。」通常、クリックして進むと、テキストファイルの両方のバージョンを並べて表示するWebベースのエディタが表示されるため、保持する行を選択できます。
そのエディタは画像用には存在しません。GitHubのブラウザベースのコンフリクト解決は、コード、Markdown、設定ファイルなどの行ベースのテキストしか理解しません。PNGやWebPファイルには、比較する「行」がありません。ボタンもビューもなく、誰かがどれだけ慎重にクリックし回ったとしても、Webサイトを通じてこれを解決できる経路はありませんでした。はっきり言っておくべきことは、コンテンツ編集者は何も間違ったことをしていなかったということです。ツールには本当にこの特定の問題を解決する方法がなかったのです。
隠れた2つ目の問題
これを修正するには、ファイルの両方のバージョンをローカルにプルし、直接比較する必要がありました。ここで、より厄介な問題が判明しました。新しいスクリーンショットがあったのは staging であり、これは実際の更新で、以前よりも大きくて高解像度でした。しかし、ペアになっているWebPファイルは長い間触れられておらず、サイズさえ一致していませんでした。新しいPNGは1024×1024ピクセルでしたが、その隣にあるWebPは完全に以前のバージョンの画像から残された750×750のままでした。
それはつまり、コンフリクトの中で単に「どちらか一方を選択」してどちらかのバージョンを丸ごと保持すると、一致しないペアが出荷されることを意味しました。PNGは新しいスクリーンショットを表示しますが、ブラウザがWebPを好む訪問者(最新のブラウザのほとんど)には、古くて間違った画像がひっそりと表示されてしまいます。コンフリクトのメッセージは消えますが、実際のバグは気づかれないまま出荷されてしまうのです。
ステップ1:両方のバージョンを適切に比較する
最初のステップは何かを解決することではありません。実際に何がどこで変更されたのかを理解するために、両方のブランチのファイルサイズと寸法を共通の開始点と比較することでした。
git fetch origin
git diff --stat origin/main origin/staging -- path/to/image.png path/to/image.webp
これにより、最後に共有されて以来、両方のブランチがファイルを個別に変更していたことがわかりました。単に「一方が新しい」のではなく、純粋な3方向の分岐です。
ステップ2:実際に正しいバージョンを特定する
両方のPNGを並べて開くことで、 staging のバージョンが間違いや破損したファイルではなく、実際の意図された更新であることが確認できました。
ステップ3:正しいソースからWebPを再生成する
2つの異なるバイナリファイルをマージしようとする(これは不可能です)代わりに、修正方法は、WebPをPNGから 派生した ものとして扱うことであり、調整する別個のファイルとして扱うことではありませんでした:
cwebp -q 82 image.png -o image.webp
これにより、新しいPNGと適切に一致する、正しい1024×1024サイズの新しいWebPが生成されました。 -q 82 は単なる品質設定であり、ファイルサイズと鮮明さの良いバランスです。
ステップ4:マージを完了して検証する
git checkout staging
git merge origin/main
git checkout --ours path/to/image.png # keep the staging PNG
cp image-regenerated.webp path/to/image.webp # use the freshly regenerated WebP
git add path/to/image.png path/to/image.webp
git commit
git push origin staging
この後、Pull Requestはクリーンでマージ可能であると表示され、ライブサイトはWebP対応かどうかに関わらず、すべての訪問者に新しいスクリーンショットを正しく提供しました。
検討され、却下された方法
途中でいくつかのより速く見えるショートカットが提案されました。それぞれ知っておく価値があり、なぜ使われなかったのかを知っておく価値があります。
デスクトップのGitクライアントでバージョンを選択する。 ほとんどのGitデスクトップアプリでは、「自分のバージョンを使用」または「相手のバージョンを使用」を選択することでバイナリのコンフリクトを解決できます。比較はなく、単に丸ごとの選択です。非技術系のチームメンバーでも自分でこれを行うことができます。問題点:古い、一致しないWebPファイルを保持することになり、上で説明したのと同じひっそりとしたバグを出荷することになります。速いですが、間違っています。
戦略フラグでマージを強制する。 コマンドラインから、 git merge origin/main -X ours (または -X theirs)は、すべてのファイルについて、尋ねるために停止することなく、片側を丸ごと選択することでコンフリクトを自動的に解決するようにGitに指示します:
git merge origin/main -X ours
これはデスクトップアプリでバージョンを選択するのとまったく同じ欠陥を持っています。Gitは競合するバイナリファイルを1つの分割できないブロックとして扱うため、内部に手を入れて一致しない半分だけを修正することはできません。
最初にベースブランチからファイルを削除する。 理論:ライブブランチにファイルがなくなれば、競合するものは何もないので、マージはクリーンに進むはずです。これは単なる推測ではなく、分離されたブランチで直接テストされました:
git rm image.png image.webp
git commit -m "test: delete file"
git merge origin/staging
結果はクリーンなマージではありませんでした。Gitはブランチが分岐した時点にファイルが存在したことを覚えているため、一方の側でファイルを変更しながらもう一方の側で削除すると、「変更/削除」のコンフリクトが発生し、独自の警告メッセージが表示されます。問題をスキップするのではなく、問題に別のラベルを付けるだけです。
コンフリクトを上書きして強制プッシュする。 より極端なオプションは、強制プッシュを介してライブブランチを他のブランチの履歴で完全に上書きすることです。これは実際のところコンフリクトの解決ではありません。一方の側の変更を完全に破棄し、他の誰かの実際の作業が知らぬ間に失われる危険を冒すものです。ライブサイトにデプロイするブランチでは、それは本当にリスクの高い行動であり、とる価値のあるショートカットではありません。
結論
バイナリファイルのコンフリクト(画像、PDF、コンパイルされたファイル、プレーンテキストではないものすべて)は、コードのコンフリクトと同じようには解決できません。推論するための行ごとの差分はありません。唯一の現実的な選択肢は、1つのバージョンを丸ごと選択するか、画像とその最適化されたコピーのように2つのバージョンが実際には一致するペアである場合に、正しいソースから派生ファイルを再生成することです。自分がどちらの状況にいるかを理解することが、戦いの大部分を占めます。
メリット
- 派生ファイル(この場合はWebP)を再生成することで、どちらの側を信頼するかを推測する代わりに、一貫性が保証されます。
- 信頼する前に、危険に見えるショートカットを分離されたブランチで最初にテストすることで、間違った思い込みを安価に発見できます。
- フォールバックとして元のファイル形式を保持すること(この場合は
<picture>要素を介して)は、一時的に壊れた最適化されたコピーでさえ、訪問者に対してページを完全に壊すことは決してないことを意味します。
デメリット
- どれも速いオプション(バージョンの選択、強制されたマージ戦略、削除して再マージ)は、一致しないペアの問題を実際には解決しません。それらはコンフリクトのメッセージを消すだけです。
- これを適切に修正するには、サーバーまたはコマンドラインへの直接アクセスと画像変換ツールが必要でしたが、これはブラウザのみ、またはデスクトップアプリのみのワークフローでできることを超えています。
- 根本的な原因(通常のレビューフローをバイパスした、ライブブランチへの直接編集)はプロセスのギャップであり、1回限りの技術的な修正では再発を防ぐことはできません。
注意
この記事は教育目的であり、実際の状況を一般的な用語で説明しています。特定のファイル名、パス、および識別子は一般化されています。ここに示されているコマンドは、実際のファイルやブランチの履歴を変更または破棄する可能性があります。常に分離されたブランチまたは使い捨てのコピーで最初にテストし、特定の状況で「ours」と「theirs」がどちらの方向を指しているかを理解し、強制的にコンフリクトを解決するものを実行する前にバックアップまたは回復する方法があることを確認してください。依存する前に、独自のリポジトリの実際の状態に対してコマンドを確認してください。
よくある質問
- GitHubのWebサイトで画像ファイルのコンフリクトを解決できないのはなぜですか? — そのブラウザベースのコンフリクトエディタは行ベースのテキストしか理解しません。そのインターフェースを通じてPNGやWebPのようなバイナリデータを比較したりマージしたりする方法はありません。
- 「変更/削除」のコンフリクトとは何ですか? — 1つのブランチがファイルを削除し、履歴を最後に共有して以来、別のブランチがそれを変更した場合に発生します。Gitは、どちらの変更を優先すべきか推測するのではなく、これにフラグを立てます。
- 一方のブランチからファイルを削除すると、マージコンフリクトは回避できますか? — いいえ。ブランチが分岐したときにファイルが存在していた場合、一方の側でファイルを変更しながらもう一方の側で削除すると、依然としてコンフリクトが発生しますが、種類が異なるだけです。
- デスクトップGitクライアントの「自分のバージョンを使用」または「相手のバージョンを使用」は、画像のコンフリクトに対して安全ですか? — それはコンフリクトを解決しますが、1つのファイルをそのまま保持することによってのみ解決します。WebPのコピーのような派生した対応物は自動的には修正されません。
- では、
git merge -X oursは実際に何をするのですか? — それはGitに対し、すべての競合するファイルについて、尋ねるために停止することなく、マージ全体で現在のブランチのバージョンを保持することによって自動的に解決するように指示します。 - WebPファイルを単にマージするのではなく、再生成するのはなぜですか? — それは元の画像の圧縮された派生物です。2つの異なる圧縮バージョンを「マージ」する意味のある方法はないため、正しいソースからそれを再作成することが唯一の正しい修正です。
- チームはそもそもこの種のコンフリクトをどのように回避するのでしょうか? — 複数の場所からライブブランチへの直接編集を許可するのではなく、ライブブランチに到達する前にすべての変更が作業ブランチを通過するような一貫したフローを1つ維持することによってです。
タグ
#git #github #webp #imageoptimization #webdev #devops #versioncontrol #mergeconflict #cicd #webperformance
Linux Server Hardening Checklist
30 practical steps to take a fresh Linux box from default to defensible. Enter your email — you'll get the PDF instantly, plus new posts on Linux, security & AI.
Free. No spam — unsubscribe in one click.


Responses
Sign in to leave a response.