問題の説明#
問題の最初は、私が Vercel に lobechat をデプロイしたことですが、私がフォークしたリポジトリは元のリポジトリからの同期に失敗することが多く、その後 Pull requests ページでリクエストを見ました。
画像には、解決する必要があるマージコンフリクトが表示されています。このコンフリクトを解決しないと、正常にマージできません。
GitHub では、Pull Request(略して PR)は、通常開発者によって発起され、プロジェクトのメンテナに対して自分のブランチの変更をプロジェクトのメインブランチにマージするように求めるリクエストです。Pull Request は、開発者がコードをマージする前に議論、レビュー、テストを行うことを可能にし、コードの品質と機能が期待通りであることを確認します。(Pull Request のタイトルをクリックすることで、提出された変更、議論、レビューの状態などの詳細情報を確認できます。)
なぜ私がフォークしたリポジトリも開発者が元のリポジトリにマージするリクエストを受け取ることができるのでしょうか?
リポジトリをフォークすると、元のリポジトリとは完全に独立したコピーが作成されます。しかし、フォークしたリポジトリで GitHub Actions や特定の自動化ツールを有効にすると、これらのツールが元のリポジトリの更新を同期するために自動的に Pull Request を作成することがあります。これは通常、あなたのフォークを上流リポジトリのコードと同期させるためです。
具体的な状況#
私はリポジトリをフォークした後( lobehub/lobe-chat
)、自分のフォークしたリポジトリが元のリポジトリと一致するように、元のリポジトリと同期する操作を実行しました(つまり、元のリポジトリの最新の変更を自分のブランチにプルしました)。コマンドを実行した際、Git は一部のファイルにコードのコンフリクトがあると報告しました。具体的なエラーは以下の通りです:
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Auto-merging README.zh-CN.md
CONFLICT (content): Merge conflict in README.zh-CN.md
Automatic merge failed; fix conflicts and then commit the result.
これは、私のフォークリポジトリ( origin
)と元のリポジトリ( upstream
)のいくつかのファイル( README.md
と README.zh-CN.md
)が変更されているため、Git がこれらのコンフリクトを自動的にマージできず、手動で解決する必要があるためです。
問題解決の思考と方法#
上記の問題に基づいて、以下のいくつかのステップで解決できます:
1. upstream
リモートリポジトリの設定#
フォーク後、デフォルトでは自分の GitHub リポジトリ( origin
)にのみ関連付けられ、元のリポジトリ( upstream
)との関連付けが設定されていません。元のリポジトリと同期するためには、まず upstream
という名前のリモートリポジトリを追加する必要があります。
git remote add upstream https://github.com/lobehub/lobe-chat.git
説明:
git remote add
:リモートリポジトリを追加するためのコマンドです。upstream
:これはリモートリポジトリの名前です(元のリポジトリをupstream
と呼ぶのが一般的です)。https://github.com/lobehub/lobe-chat.git
:元のリポジトリのアドレスです。
以下のコマンドでリモートリポジトリが正しく設定されているか確認できます:
git remote -v
出力例:
origin https://github.com/<your-username>/lobe-chat.git (fetch)
origin https://github.com/<your-username>/lobe-chat.git (push)
upstream https://github.com/lobehub/lobe-chat.git (fetch)
upstream https://github.com/lobehub/lobe-chat.git (push)
2. 元のリポジトリから最新のコードをプルする#
upstream
を設定した後、元のリポジトリの最新のコードをローカルにプルできます:
git fetch upstream
これにより、 upstream
リポジトリのすべての更新が取得され、ローカルに更新された参照( upstream/main
)が形成されます。
次に、 upstream/main
の最新の変更を自分のブランチ(仮に main
ブランチとします)にマージする必要があります:
git checkout main # メインブランチに切り替えます
git merge upstream/main # 元のリポジトリの更新を現在のブランチにマージします
すべてが順調に進めば、Git は自動マージを完了しますが、以前にコンフリクトが発生したため、Git は以下のエラーを表示し、停止します:
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Auto-merging README.zh-CN.md
CONFLICT (content): Merge conflict in README.zh-CN.md
Automatic merge failed; fix conflicts and then commit the result.
3. マージコンフリクトを解決する#
この時点で、コンフリクトファイルのコンフリクト問題を手動で解決する必要があります。
3.1 コンフリクトファイルの特定#
以下のコマンドを実行して、どのファイルにコンフリクトがあるかを確認します:
git status
出力には、コンフリクトのあるファイルが both modified
としてマークされます。例えば:
both modified: README.md
both modified: README.zh-CN.md
3.2 ファイルを編集してコンフリクトを解決する#
エディタ(例えば VS Code)を使用して、これらのコンフリクトファイルを開きます。Git はコンフリクト部分に特別なマークを追加します。形式は以下の通りです:
<<<<<<< HEAD
(ブランチ HEAD のコード内容)
=======
(upstream/main からのコード内容)
>>>>>>> upstream/main
必要に応じて編集し、どの部分の内容を保持するか、または両方の内容をマージするかを選択する必要があります。例えば:
現在のファイル内容(コンフリクト前)
<<<<<<< HEAD
私が修正したREADMEの内容がここにあります。
=======
上流リポジトリからの新しい更新があります。
>>>>>>> upstream/main
コンフリクト解決後(調整後)
両方の内容を保持し、マージした後:
私が修正したREADMEの内容がここにあります。
上流リポジトリからの新しい更新があります。
編集が完了したら、ファイルを保存し、コンフリクトマーク( <<<<<<<
, =======
, >>>>>>>
)がすべて削除されていることを確認します。
3.3 コンフリクト解決完了のマーク#
コンフリクトを解決した後、修正したファイルをステージングエリアに追加します:
git add README.md README.zh-CN.md
または、ワイルドカードを使用してすべてのファイルを一度に追加します:
git add .
3.4 マージ結果をコミットする#
すべてのコンフリクトが解決され、ステージングエリアに追加された後、今回のマージ解決結果をコミットします:
git commit -m "READMEファイルのマージコンフリクトを解決"
4. ローカルの変更をリモートリポジトリにプッシュする#
マージが完了したら、ローカルの変更を自分のフォークリポジトリにプッシュします:
git push origin main
この時点で、GitHub 上にあなたのブランチが元のリポジトリと同期していることが表示されます。もしこれが GitHub 上の Pull Request のコンフリクトを解決するためであれば、今すぐ GitHub サイトで PR をマージすることができます。
まとめ#
これは Git のマージコンフリクト処理の完全な実践です。上記の操作を通じて、私はファイルのコンフリクト問題を成功裏に解決し、元のリポジトリの更新を自分のフォークリポジトリに同期させることができました。
- 問題:元のリポジトリの更新を同期する際、2 つのブランチが同じファイルに対して異なる変更を行ったため、マージコンフリクトが発生しました。
- 解決策:
- 元のリポジトリの更新を設定し、プルします。
- 更新を現在のブランチにマージする際、コンフリクトファイルを特定します。
- 手動でコンフリクトファイルのマークされた内容を解決し、適切なコードを保持します。
- 修正をコミットし、リモートリポジトリに更新をプッシュします。
関連する重要なコマンドのまとめ:
upstream
リモートリポジトリを追加:git remote add upstream <url>
- プルして元のリポジトリと同期:
git fetch upstream git merge upstream/main
- コンフリクトファイルを確認:
git status
- 自動または手動でコンフリクトを解決した後、変更をコミット:
git add <file> git commit -m "Resolve conflicts" git push origin main
この実践を通じて、私は Git のマージコンフリクト解決プロセスについてより深く理解しました。元のリポジトリを同期する場合でも、複雑なチーム協力のシナリオを処理する場合でも、これらのスキルは非常に重要です。似たような問題を抱えている仲間に役立つことを願っています!