共同開発の基本
GitHub Flow に従った共同開発の現場において、個人の作業は以下の繰り返しです。
- main からブランチを生やす
- ブランチ内でコミットをしていく
- 変更が済んだらプルリクエストを立てる
- main にマージする
ここまでの操作で全て体験できましたね。この章ではそれぞれの操作の意味を明確にします。
プルリクエスト
プルリクエスト(Pull Request, PR)という機能はバージョン管理ツールとしての Git 自体には存在せず、GitHub や Gitea などのホスティングサービスの側が提供しています。前章では色々とすっ飛ばしてマージまで行ってしまいましたが、共同開発では本来ここで変更点に問題がなさそうか、チームの審判を仰ぐためのワンクッションとして機能するものです。
プルリクエストは「プルのリクエスト」ではない
プルリクエストの趣旨は「このブランチを main に マージ してほしい」であって、その先の「このブランチがマージされたら各自で main を プル してほしい」ではありません。歴史的経緯から「プルリクエスト」という名前で今まで通ってきたものの、ややこしいという指摘は未だに受け続けているようです。GitHub や Gitea では「プルリクエスト」と呼ばれていますが、他の著名なホスティングサービスの一つである GitLab では「マージリクエスト」というより直感的な表現が使われています。
マージという言葉には前編で説明した以上の意味があることがお分かりになるかと思います。一般に「ブランチの変更内容同士を統合すること」をマージと呼びます。
「sub → main のマージ」とは main ブランチから sub ブランチを生やした分岐点以降の main と sub それぞれの変更を統合して main に反映させることを意味します。ところが、前章までの実習では sub ブランチをマージするまでの間 main ブランチに何も変更を加えていないので、マージによって main に sub の変更がそのまま反映されたのです。
マージ元はマージの影響を受けない
sub の変更を main にマージした直後でも sub と main が全く同じ状態になるとは限らないことに注意が必要です。マージされるのは「状態」ではなく「変更」なので、sub ブランチの中で変更された箇所以外の sub ブランチの内容は main には影響を与えません。
sub をマージしてもファイル A の状態が戻るわけではない
ブランチが途中で生えたりマージされたりするとコミットグラフはこんな感じになります。
ブランチという命名について
そもそも、ほとんどの場合「あとで main にマージする」ために生やすものを「木の枝(ブランチ)」と呼ぶのもちょっと変な話ではありますね。上の図のようにブランチがマージしてしまったら、コミットグラフは少なくともグラフ理論における「木」の定義には当てはまらないものになります。ブランチがちゃんと「枝」っぽく見えるのは、そのブランチがマージされていない間だけです。
Gitea の機能
Gitea など多くのホスティングサービスは共同開発の効率化のために様々な機能を提供しています。これらはプルリクエストと同じく Git には存在しない機能です。
Issue ... Gitea や GitHub には、そのプロダクトについて「現状の問題点」とか「やるべきこと」をメモ・共有するために Issue を立てる機能があります。Issue にはその問題点の性質を示すタグをつけることができます。traQ フロントエンドリポジトリ の Issues を見るとこの機能の意義が掴めると思います。
レビュー ... 立てられたプルリクエストにおける変更に問題がなさそうかを検証することです。Gitea 上でもレビューをするための UI や機能が提供されていて、1 人以上の Approve がなければプルリクエストのマージができないような設定にすることもできます。
Git without ホスティングサービス
Git は独立したソフトであり、GitHub や Gitea などのホスティングサービスなしに活用することができます。とはいえ、ホスティングサービスが提供する機能も非常に便利なので、セキュリティ上の懸念など特殊な事情がない限り Git とホスティングサービスは一緒に使うのが一般的です。ちなみに、traP にはホスティングサービスに頼らない Git 開発の経験がある人もいるみたいです。
README.md とは何か
これまで README.md というテキストファイルを編集しながら Git の操作を学んできました。
README.md は Gitea などのホスティングサービスによって特殊な扱いを受けるファイルです。具体的には、もし Git リポジトリの中に README.md というファイルが含まれていれば、Gitea 上のリポジトリのページではそのファイルの最新の状態を大きく表示します。
「私を読んで!」という意味の名前から察されるように、この README.md というファイルは本来開発者がそのリポジトリで何を開発しているかの説明を Markdown 形式で書くためのものです。traQ フロントエンドリポジトリ の README.md などはよい書き方の例です。
とはいえ、リポジトリを開発以外の用途に供していたり、そもそも非公開に設定していたりする場合、README.md を詳しく書く必要はありません。この講習会では、README.md を単に『Gitea 上で最新の状態をすぐに確認できる体のよいテキストファイル』として編集していただくことにしました。
リポジトリは壊せない
最後にこの Git 講習会で最も知ってほしいことを書くとするなら、「初学者に Git リポジトリは壊せない」ということです。Git が単に「共同開発のためのツール」であることしか知らなければ「素人が適当に操作すると手軽に全てを台無しにしうる」という先入観を抱いても無理はありません(筆者もそうでした)。ところが実際はその逆で、Git リポジトリはたとえ知識がある人でも復元不能に追い込むことは難しいのです。
ブランチを勝手に作成
既存のリポジトリに勝手にブランチを生やすことは、開発の本筋にさしたる影響を与えません。それどころか気付かれもしないかも知れません。気軽にいじくってみましょう。
main にコミット & ブランチを勝手にマージ
リポジトリには過去のあらゆる状態の履歴が残っています。単にコミットを過去に戻せばよいだけなので、知識がある人なら復元には 5 分とかかりません。まして厳格な開発ならブランチに保護がかかっていたりして、勝手にマージすることは物理的に不可能だったりします。
リポジトリを削除
もしあなたが相当な曲者で、Gitea 上でリポジトリの削除ボタンに手を伸ばす勇気があったとしたら、確かに一瞬だけ Gitea からリポジトリは消滅します。ところが、それが個人開発のリポジトリならともかく、共同開発においては協力メンバー一人一人の手元にリポジトリのほとんど完全なコピーが残っているので、誰かがそれを新たに Gitea にアップロードすれば何事もなかったかのように開発は続いていきます。
あなたがどれほど Git リポジトリを下手に扱ったとしても、共同開発を立ち行かなくさせることはできません。それを知っていれば必要以上に Git の使用を怖がらずに済むでしょう。それでも不安は不安だ、という人は、Git + Gitea を単なる iCloud Drive や OneDrive の代わりとして普段使いしてみるとよいと思います。手に馴染ませるほど、Git は今まで敬遠していたのが嘘のように堅牢で便利なツールであると分かってくるはずです。
#event/workshop/git/exercise の『後編完走』にスタンプをつけよう!