シナリオ:2 人が同じ Git ブランチを維持するシミュレーション。
まず、Github リポジトリで master
を基に新しいブランチ feature/add_git_cmds
を作成し、Create branch をクリックします:
作成が成功したら、ローカルに戻り、ローカルで 2 つのリポジトリをプルして、2 人が開発するシミュレーションを行います。
2 人に異なる user を設定するのを忘れないでください~
まず、Git リポジトリのグローバル設定( --global
)を見てみましょう:
git_learning_A にはデフォルトのグローバルユーザー設定を使用させ、git_learning_B にはローカルユーザー設定( --local
、グローバル設定より優先されます)を設定します:
(設定は1 Git 基礎 --03|git を使用する前に行う最小限の設定を参考にしてください)
最後に、2 つのローカルリポジトリで、リモートのfeature/add_git_cmds
ブランチを基に関連付けられたローカルブランチを作成します。
コマンド: git checkout -b feature/add_git_cmds origin/feature/add_git_cmds
、このコマンドは後ろのリモートブランチを基に前者の名前のローカルブランチを作成し、リモートブランチを追跡し、新しく作成したブランチに切り替えます。
2 つのローカルリポジトリで同様の操作を行います。
これで、2 人が同じリポジトリの同じブランチで開発するシナリオをシミュレートしました。次に、5 つの状況について一つずつ実験してみましょう🧪!
34 | 異なる人が異なるファイルを修正した場合の対処法は?#
結論:直接マージすればよいです。
git_learning_A:readme.md ファイルを修正し、リモートにプッシュします。
git push
は非常にスムーズに行きました。
リモートリポジトリを確認します:
コミット履歴の著者を確認すると、git_learning_A が使用しているグローバルユーザー設定に対応しています:
git_learning_B:別のファイル xxx/css.x を修正し、プッシュする前にまずプルし、次にプッシュを試みます。
まずファイルを修正し、直接プッシュするとどうなるか見てみましょう?
前のステップは git_learning_A と似ていますが、 git push
の際に予期しない事態が発生しました。これは見覚えがありますか?エラーは前の章で言及したものと全く同じです:3 Git と GitHub の簡単な同期 --33 | ローカルリポジトリを GitHub に同期する。
❌: git push -f
強制プッシュ。
✅:まずプルし、次にマージし、最後にプッシュします。
git fetch
:
最新のコミットのハッシュ値が d7d648a から 192a3b3 に更新されたことがわかります。
ブランチの説明で、現在のブランチとリモートブランチの状態は:ahead 1(ローカルに更新があり、リモートにプッシュしていない)、behind 1(リモートに更新があり、ローカルに取り込んでいない)となっていますので、まずはマージを行います。
git merge origin/feature/add_git_cmds
:
実行後、コミット情報の編集がポップアップし、デフォルトのままで、または適切に説明を追加します。
:wq
で保存して終了すると、マージが成功し、修正の記録が確認できます。
青い線で現在の状態が ahead 2 であることがわかります。つまり、ローカルには 2 つのコミットがあり、まだリモートにプッシュされていません;
赤い枠は ahead の 2 つのコミット記録です。
この時点で、ローカルの readme.md と xxx/css.x ファイルはどちらも修正された状態になっており、次に直接プッシュすればよいです。
git push
:
プッシュ成功!異なる人が異なるファイルで協力して作業するのは非常に便利ですので、協力作業はこの方法で行うと非常に効率的ではないでしょうか?他の状況も見てみましょう~
35 | 異なる人が同じファイルの異なる領域を修正した場合の対処法は?#
結論:直接マージすればよいです。
⚠️:まず異なる領域のある環境を作成し、いずれかのリポジトリの readme.md ファイルに複数行を追加し、プッシュして、2 つのリポジトリを同期させます。readme.md ファイルの修正は以下の通りです:
前のセクションのファイルは 1 行だけだったため、異なる領域を修正することはできませんでした。
git_learning_A:readme.md の第 4 行を修正し、直接プッシュします。
git_learning_B:readme.md の第 7 行を修正し、まずプルしてからプッシュします。
git pull
の過程で、コミット情報の編集がポップアップし、 :wq
で保存して終了すると、マージが成功します。
⚠️:ここで直接プルすると、明確なプル戦略がないため推奨されません。
1)プルのデフォルト戦略を手動で設定できます。
2)または、 git pull
コマンドの後にオプションを追加します。例えば --rebase
、 --no-rebase
、 --ff-only
など。
3)または、 git fetch
の後にマージ戦略を選択します。
この時点でローカルの readme.md ファイルを確認すると、期待通りの内容になっており、次に直接プッシュすればよいです:
この方法での協力作業も比較的スムーズで、Git は自動的にマージする能力があります~
36 | 異なる人が同じファイルの同じ領域を修正した場合の対処法は?#
結論:マージ時に衝突が発生し、自分で解決する必要があります。
git_learning_A:readme.md の第 1 行を修正し、直接プッシュします。
⚠️:まず git pull
を行うのを忘れないでください。なぜなら、先ほど git_learning_B が行った更新がまだ同期されていないからです。
git_learning_B:同様に readme.md の第 1 行を修正し、まずプルしてから手動で衝突を解決し、次にプッシュします。
今回は git pull
にオプション --no-rebase
を付けて、マージ方式でプルを行います。
続いて、衝突が発生し、衝突を自分で解決する必要があります。その後、コミットを行います。
vim readme.md
で衝突が発生したファイルを開きます:
衝突の位置には明確なマークがあり、HEAD と === の間はローカルのコード、ハッシュ値と === の間はマージされたコードを示しています。
この部分のコードを修正し、これらの特殊なマークを削除する必要があります。以下のように修正できます:(実際の開発では、関連する人とコミュニケーションをとった後に修正してください❗️)
:wq
で保存して終了した後、 git status
でリポジトリの状態を確認します:
赤い枠の上はマージを行うことを示し、下はマージをキャンセルし、マージ前の状態に戻ることを示しています。
ここで上の方を実行してみましょう。⚠️:この時点での修正はまだ作業ディレクトリにあり、まずはステージングエリアに追加し、その後コミットする必要があります。
追加とコミットを行い、次にプッシュします:
PS: -am
は追加とコミットの 2 つの操作を含みます。
今回は Git がそれほど賢くないことがわかりましたが、実際にはそれほど賢くある必要もありません。なぜなら、誰のコードを保持すべきかを知ることはできないからです。
37 | 同時にファイル名とファイル内容を変更した場合の対処法は?#
結論:直接マージすればよいです。
git_learning_A:xxx/css.x のファイル名を xxx/css2.x に変更します。
git mv
コマンドを覚えていますか?1 Git 基礎 --06 | ファイルを簡単にリネームする方法を見て復習してください。
git_learning_B:xxx/css.x の内容を修正します(ファイル名が変更されたことを知らない)。
素晴らしい~Git はこのような問題を自動的に解決できます。マージの状況を確認します:
ファイル名が変更されただけでなく、ファイル内の変更も保持されていることがわかります。
本質的に、ここで変更されたのは同じファイルの異なる領域です~
38 | 同じファイルを異なるファイル名に変更した場合の対処法は?#
結論:マージ時に衝突が発生し、自分で解決する必要があります。
git_learning_A:xxx/css2.x のファイル名を xxx/cssA.x に変更します。
git_learning_B:xxx/css2.x のファイル名を xxx/cssB.x に変更します。(ファイル名が変更されたことを知らない)。
衝突が発生しました~
ファイルの状況を確認します:
Git の処理は両方の変更されたファイル名を同時に保持することであり、2 つのファイルの内容は同じです。
git status
でファイル名の変更状況を明確に示し、どうすればよいかを教えてくれます。
不要なファイルは git rm
で削除し、必要なファイルを git add
で追加し、コミットしてプッシュすれば完了です!
これらのシナリオでの Git による協力作業を見て、衝突を解決することへの恐怖がなくなりましたか?