GitHub でのチームの共同作業
学習の目的
この単元を完了すると、次のことができるようになります。
- GitHub ワークフローをチームの効率的なブランチ戦略に変換する。
- GitHub のマージ競合を解決する。
- 単一の作業単位を表すアトミックコミットを作成する。
機能するブランチ戦略
独自で作業する場合の GitHub の簡単なサンプルフローを実行しましたが、このワークフローがチームではどのように機能するのかを想像してみてましょう。ブランチ、コミット、およびプルリクエストの数が、チームの人数や進めている開発の数に応じて倍増します。現在までに多数のチームがこれを経験しており、成功パターンが蓄積されています。
一般にブランチは、1 つの機能を完成させる目的で短期的に使用され、マージ後に削除されます。ブランチを短期的に用いることで混乱を防ぎ、コードを最新の状態に保ち、開発者がプロジェクトを反復的な方法で改良できるようにします。
長期的なブランチは、慎重に使用しなければ問題が生じるおそれがあります。開発ブランチや、コードに複数の開発レベルが必要な状況などでは、長期的なブランチが適していることもあります。長期的なブランチの問題の大半は、開発者の各ブランチが最新バージョンでないため不必要なマージ競合や混乱、作業が生じることに起因します。ブランチワークフローを複雑にすれば問題が解消されるように思えるかもしれませんが、複雑になり過ぎることが少なくありません。GitHub フローはシンプルなほど効率的に機能します。
ブランチについてチームに以下のような質問をします。
- どのブランチ戦略を採用するのか?
- どのブランチをメインにするのか? リリース済みのコードであるブランチはどれか?
- ブランチに命名規則を採用するのか?
- ラベルと担当者をどのように使用するのか?
- マイルストーンを使用するのか?
- プロジェクトボード (プロジェクト) を使用するのか?
- イシューまたはプルリクエストに必須テンプレート/要素を設定するのか (出荷チェックリストなど)?
- プルリクエストにサインオフをどのように表示するのか?
- プルリクエストを誰がマージするのか?
前述のとおり、ブランチの最大のメリットは、安全な場所で変更を行えること、そしてプルリクエストでレビューやテストを実施できることです。チームがブランチに何を期待しているのかを判断したら、できる限りコンパクトでわかりやすいものにします。コラボレーションを重視します。
マージ競合の処理
チームで共同作業するときに (時として単独で作業するときにも)、マージ競合が生じることがあります。最初はマージ競合に怖じ気づくかもしれませんが、実際のところ、ごく簡単に解決できます。
では、マージ競合を作り出して、どうなるかを見てみましょう。
コミットが競合している複数のブランチの作成
ご存知のとおり、マージ競合が生じるのは、別々のブランチの同じファイルの同じセクションに複数のコミットが存在する場合です。そこで、競合の解決を練習するために、競合を設定してみましょう。
- メインから、新しいブランチ (new-branch-1) を作成し、README.md ファイルに変更を加え、プルリクエストを作成します。
-
git checkout -b new-branch-1
コマンドを入力します。 - リポジトリの README.md ファイルに変更を加えます。どの行を変更したのかをメモしておきます。
- new-branch-1 で、変更を加えてコミットします。
git add README.md コマンドを入力します。
-
git commit -m "Changes to the README"
コマンドを入力します。
-
-
git push -u origin new-branch-1
で、ブランチをリモートリポジトリにプッシュします。 - GitHub を開いて、このコミットのプルリクエストを作成します。
- ここで、次のブランチおよびプルリクエストを作成するために、もう一度メインにチェックアウトします。
git checkout main
- 新しいブランチ (new-branch-2) を作成して、同じファイルに変更を加え、プルリクエストを作成します。
-
git checkout -b new-branch-2
コマンドを入力します。 - README.md ファイルの同じ行に変更を加えます。
-
git add README.md
コマンドを入力します。 -
git commit -m “More changes to the README”
コマンドを入力します。 -
git push -u origin new-branch-2
コマンドを入力します。 - GitHub で、プルリクエストを作成します。
-
1 つのプルリクエストのマージ
この時点では、まだどちらのブランチにもマージ競合が表示されていません。GitHub で、1 つ目のプルリクエストを (new-branch-1 から) マージします。
他のブランチの競合の解決
new-branch-1 のプルリクエストをマージしたら、new-branch-2 のプルリクエストに移動します。
マージ競合が生じていることがわかりますね。焦ることはありません。解決できます。マージ競合がどのくらい複雑なのかによって、GitHub のブラウザーで解決可能な場合もあれば、ローカルで解決する必要がある場合もあります。
ローカルで解決するには、メインをブランチにマージして、競合を解決してからマージを完了します。
-
git checkout new-branch-2
で、競合のあるブランチにチェックアウトします。 -
git pull
で、ローカルリポジトリを最新の状態にします。 -
git merge origin/main
で、メインを機能ブランチにマージします。マージ先はリモート追跡ブランチであって、メインのローカルコピーではありません。これは、pull コマンドによってリモートブランチと現在開いているブランチは更新されているものの、メインが更新されていないためです。 - 競合の存在が示されていれば OK です!
git status
と入力して、どのファイルに競合があるのかを確認します。Unmerged Paths
の下に、競合のあるファイルがリストされます。 - テキストエディターで該当するファイルを開き、マージ競合のマーカー。 (
<<<<<<<
,=======
,>>>>>>>
) - ブランチの両方のバージョンのコードが表示されています。残すコードを選び、もう一方を削除します。Git によって作成されたマージ競合のマーカーを削除して、変更を保存します。
- マージ競合を解決するために保存された変更を追加してコミットします。
-
git add README.md
コマンドを入力します。 -
git commit -m “Commit to resolve merge conflict”
コマンドを入力します。
-
-
git push
で、機能ブランチをリモートにプッシュします。 - GitHub のプルリクエストに戻ります。この時点でプルリクエストに競合はありません。
- プルリクエストをマージします。
上記のブランチを処理したら、GitHub の該当するブランチを削除し、git checkout main
と git pull
コマンドを使用してローカルリポジトリを同期させます。
アトミックコミットの作成
参照可能で有益なプロジェクトの履歴を作成するにあたって、重要な要素となるのが、アトミックコミットの作成です。
理想とするのは、履歴の内容を確認したり変更したりする必要がない世界です。残念ながら、そんな理想的な世界は望めないため、必要に応じてバージョン管理によって変更履歴を確認できるようになっています。コミットはそれぞれ、小規模で論理的な変更単位であり、リポジトリのストーリーを伝えるものです。
では、アトミックコミットの作成に役立つ git add --patch
というコマンド (短縮形は git add -p
) の使い方を練習してみましょう。このコマンドは、ファイルの各部をステージングエリアに追加することができ、真に論理的な変更単位をコミットする場合に役立ちます。
- bigFile.md をコンピューターにダウンロードします (場合によっては、右クリックして [Save Target As (対象をファイルに保存)] を選択する必要があります)。
- GitHub で、bigFile.md を best-repo-ever リポジトリのメインブランチにアップロードします。
- [Upload files (ファイルをアップロード)] をクリックします。
- コンピューターで bigFile.md を選択します。
- [Commit directly to the main branch (メインブランチに直接コミット)] を選択します。
- [Commit changes (変更をコミット)] をクリックします。
- ローカルのメインリポジトリが最新の状態であることを確認します。
-
git checkout main
コマンドを入力します。 - 「
git pull
」コマンドを入力します。
-
-
git status
で、Git で追跡している内容を確認します。コミットするものが何も存在しないことがわかります。 - bigFile.md の 1 行目と 100 行目に変更を加えます。(変更内容は何でも構いません)。
-
git add -p
に --patch フラグを設定して、いくつかのファイルの一部をステージングエリアに移動します。 -
[y]
を押してハンクをステージングします。これは変更単位に対する Git 言語です。
ハンクにどのようなオプションがあるのか気になる場合は、?
を使用すると、ハンクの上にオプションリストが表示されます。