「アジャイルなら Git」の神話

2021年5月24日公開

背景

ここ数年、職場でも Git を使うことがわりと当たり前になってきました。筆者が個人的に Git を使い始めた頃、こんな複雑なバージョン管理は職場で普及しないだろうと思っていました。何より Subversion では積極的に使う気になれなかったブランチを誰もが作ってマージしたりするとは想像できませんでした。

それが今ではどうでしょう。アジャイル開発関連のプレゼンテーションを見てみると、そのほとんどが Git を利用しているようです。Subversion を利用している事例はほとんど見かけません。アジャイルなら Git を利用することがデファクトスタンダードのように見えます。

そんなある日、社内で先輩に言われたことがあります。

「Git はフォークやブランチによって派生を促す傾向が強く、イノベーションを生む OSS に向いている。一方で分断を助長し、アジャイルが志向する常時結合を阻害する側面もある。」

最初に聞いたとき、なんとなく分かるも、釈然としないところもありました。 ブランチを手軽に作って機能の開発に集中できることこそ Git の強み であり、Subversion などほかのバージョン管理システム(VCS)と差別化される特徴だと思っていたからです。

もちろん常時結合(CI: Continuous Integration)の意味や目的は、唯一のコードベースを動作する状態で維持し、そのコードベースを基点にして全ての開発者が共有し、進化させることにあります。

ですから、Git の便利な機能は、その使い方に気を付けないと逆にアジャイルな開発からは遠ざかってしまいそうです。機能の開発に集中できるということは、言い換えればほかの開発者やブランチのことを無視した、ひとりよがりな開発になるかもしれません。

Git の強みである「手軽さ」や「軽快なブランチ機能」を活かしながら、唯一のコードベースへの常時結合を志向する「よりアジャイルな開発」を実現するにはどうしたら良いのでしょうか。

トピックブランチの功罪

Git で一般的に使われるトピックブランチの功罪について改めて整理してみます。

なお、 トピックブランチ (注釈1)とは「一つのテーマ(トピック)に集中して、その上では一つのテーマを解決する以外の仕事はしないようなブランチ」のことです。一方、「トピックブランチを分岐する元になり、また、完成したトピックブランチでの変更を併合するブランチ」は 統合ブランチ (注釈1)と呼びます。一般には mastermain ブランチを統合ブランチに当てます。

開発者たちにとっての利点

前述したとおり、機能の開発に集中できることがブランチの利点でしょう。

  • 統合ブランチからの影響を避けられる
    トピックブランチで開発を進めている間に統合ブランチが進んだ(追加のコミットがあった)としても、別のブランチですから影響を受けることなく開発を継続することができます。
  • 統合ブランチへの影響を避けられる
    レビューやテストが不十分なままコミットしても、それが統合ブランチでなければ統合ブランチへの影響を避けることができます。
  • 開発途中のコードをローカル以外に残せる
    機能の開発がすぐに終わりそうにないとき、ブランチを分けていなければ完成するまでローカルディレクトリーに変更を残し続けなければなりません。
    しかし、ブランチを分けてコミット(プッシュ)しておけば、もし翌日、ローカルの環境が壊れたり、急用(病気とか含めて)で続けられないときにも引き継げるので安心です。
  • コミットを使ってレビューできる
    GitHub や Bitbucket のプルリクエスト、GitLab のマージリクエストを使ってコードの変更差分を確認しながらレビューをすることができます。差分の中にレビューのコメントを残すことも簡単です。

常時結合を志向するアジャイル開発にとっての弊害

トピックブランチを使って複数の開発者がそれぞれ集中して開発できることは、一個流し(注釈2)の阻害、すなわち WIP(注釈3)の増加の要因にもなり、様々な弊害を生みます。

  • 統合ブランチとの乖離によるコンフリクト
    複数人で開発していれば、ブランチで分かれて開発している間に統合ブランチも変化します。その期間が長くなるほど、コンフリクトが発生しやすくなります。コンフリクトしたらそれをマージするときに解消しなければなりません。
  • 常時結合の阻害
    トピックブランチ上で CI ツール等を使って自動テストをしていたとしても、そのときの統合ブランチの変更が反映されていないわけですから、Continuous Integration、つまり継続的に統合できている状態とは言えません。
  • レビュー機会の減少
    それぞれの開発者はそれぞれのトピックブランチを使って開発しているわけですから、完成前でもドラフトのプルリクエストを作って頻繁にプッシュするなど工夫と意識付けをしないと、レビューがマージの直前だけになってしまいそうです。

トランクベースとトピックブランチの開発の比較

Git のトピックブランチを利用した開発がそれほど普及していなかった頃、つまり Subversion を使っていた頃はトランクベースでの開発が一般的でした。Subversion のブランチはその機構上、動作が重く、機能的にも決して使い勝手が良いものとはいえなかったからでしょう(注釈4)。また、Subversion は分散リポジトリーではないため、Git ほどにはブランチを利用する旨味が少なかったからでもあるでしょう。

ここで、Subversion でよく用いられるトランクベース開発と Git でよく用いられるトピックブランチベースの開発、それぞれにおける特徴を整理してみます。

トランクベースで開発 トピックブランチによる開発
タスクやストーリーへの集中 統合ブランチの変更に常に対処する必要がある 統合ブランチや他のブランチの変更を気にせず集中できる
プロジェクトへの参入障壁 高い(統合ブランチにコミットできる権限が必要) 低い(フォーク/クローンしたリポジトリーがあれば良い)
プルリクエスト機能 使えない 使える
WIP コミットを短時間でトランクに反映するため少なく抑えやすい コミットをブランチで保持するため増えやすい
タスクやストーリーの大きさ コミットを短時間でトランクに反映できるように小さくしようとする力が働く ブランチで隔離できるため小さくする動機が起きにくい
レビュー 統合された状態で継続的にレビューできる マージ前にレビューできる(特に開発者のスキルに懸念がある場合に有用)
継続的インテグレーション コミットする度に実施 ブランチをマージしたときのみ実施(マージ前のブランチをプッシュして CI ツールでテストを実行することは可)

開発者にとってトピックブランチを使った開発、つまり Git の軽快なブランチ機能を利用した開発は、ほかの開発者やほかの機能を気にすることなく心地よいものです。

一方、アジャイルという観点で見ると、唯一のコードベースを維持し、全ての開発者がそれをもとに開発できることが理想です。それを実現するためには WIP を最小化し常時結合することが必要になります。

やはり、Git の便利で軽快なブランチ機能と、常時結合を志向するアジャイル開発の間に何らかの調和が必要そうです。

トピックブランチによる開発

Git が普及したのは GitHub の影響が大きいでしょう(筆者もそうでした)。

GitHub が OSS のフォークを簡単なものにし、プルリクエストなどを使ったソーシャルコーディングへと発展しました。従来、メーリングリスト等で行っていたであろうパッチの説明やレビューをプルリクエストは容易なものにしました。

ソーシャルコーディングの開発スタイルは、OSS でなくても便利に使うことができます。

Git ならタスクやユーザーストーリー毎にブランチを分けることも簡単です。一つのユーザーストーリーが完成するまでの間、ほかの開発者のコミットからは少し距離を置いて開発に集中することができます。コーディングが終わったらマージ前のブランチを同僚にレビューしてもらい、テストがパスすることを確認してから統合ブランチにマージすれば良いのです。そして、このマージまでのプロセスに GitHub などが持つプルリクエストの機能がそのまま使えます。

このソーシャルコーディング由来の開発スタイルが普及するとともに、トランクベースの開発スタイルが減っていったと考えられます。

また一方で、トピックブランチによる開発はその扱いに注意しないと、WIP の増大や、ブランチが長くなって多くのコンフリクトを誘発することになります。

トランクベースでの開発

Subversion の場合

Subversion は集中型リポジトリーですので、コミットがすなわちチームで共有しているリポジトリーへの反映を意味していました。

このとき、コミットする前にもし別の人がコミットしていた場合、 svn update によって先に行われたコミットを 作業ディレクトリー にマージ(場合によってはコンフリクトの解消も)しなければなりません。


このコミット前の 一連のプロセスによって常時結合するよう制約していた ことになります。

Git の場合

さて、Git でトピックブランチを作らなかったらトランクベースの開発となるでしょうか。

Git では、リモートリポジトリー(ブランチ)の変更をローカルに反映するのに git pull を使います。

通常は、ローカルリポジトリーでリモートに未反映のコミットがなければ、リモートの変更がローカルリポジトリーにそのまま反映されます(fast-forward マージ)。


一方、ローカルリポジトリーでリモートに未反映のコミットがあれば、それぞれのコミットはそのまま残され、更にそれぞれのコミットをマージまでできます。


つまり、細かくコミットの分岐や統合が発生することはあるものの、設定やオプションの使い方に気を付ければ、 トランクベースで開発を進めることは Git でも実現できそうです。

Subversion と比べて安全な Git

Subversion ではコミット前の作業ディレクトリーとトランクの最新のコミットを常にマージしながら開発しています。

もし、マージに失敗して最初からやり直したくなったとしても、変更したファイルは作業ディレクトリーのみにしかないため元に戻せなくなる危険性があります。

Git ではローカルにコミットした後、リモートの最新のコミットとマージしながら開発します。

このため、マージに失敗しても変更前のファイルはローカルにコミットしていますから、そこから元に戻して最初からやり直すことができます。

常時結合を志向したトランクベースの開発であっても、Subversion より安全で、しかも軽快で使い勝手の良い Git の特徴を活かすのが良さそうです。

Git で WIP の最小化を目指す

Git を利用し、Git のトピックブランチを利用する。その際、トピックブランチを短く小さくなるように工夫したらどうでしょう。ブランチを簡単に作ることもできれば手軽に捨てられるのも Git ならではです(注釈5)。トピックブランチに対応する タスクやストーリーをテスト可能な最小単位にまで小さくする ことによって、WIP を 1に固定したトランクベースと言わないまでもアジャイルの志向する WIP を削減し、継続的インテグレーションを活かした開発に近付けることができるのではないでしょうか。

もちろん、「最小単位にまで小さくする」とはいっても実現の難易度は決して低くはありません。難易度はソフトウェアの構造に起因しますし、その構造は開発者の能力に依存するからです。しかし、WIP の最小化にむけて、より良い構造とより良い設計を目指す開発者たちの行動が、開発者たちの能力向上とソフトウェア構造の改善に繋がるでしょう。

むすび

これを書くにあたり、入門Git - 秀和システム を読み返しました。少し古い本で、コマンドのデフォルトの動作など今とは変わっているところもありますが、ツールの基礎からその思想をふりかえるのは改めて良い学びになりました。

GitHub などのコードホスティングもどんどん使い易くなっていますが、機能の使い方に目を奪われて、自分達のやりたかったことと合っているのか考えることが減ったかも知れません。

Git の成功したブランチモデルとして 2010年に git-flow が公開されましたが、これを提唱した Vincent Driessen 氏はその10年後、ブランチの扱い方に万能薬はなく、どのようなやり方が適しているかは自ら考えなければならないと注意を付け加えています。

迷ったときこそ、慣習にとらわれず、基本に立ち戻って自ら考え直す良い機会になります。

注釈

  • 注釈1
    濱野純「入門Git」7.6 より引用。
  • 注釈2
    「一個流し」については アジャイル開発とは(後編)スクラムとXPの調和 を参照。
  • 注釈3
    Work In Progress(または Work In Process)の略。 アジャイル開発の進捗管理(番外編)在庫はリードタイム も参照。
  • 注釈4
    「Subversion だとブランチを作るのが恐ろしい。ソースファイルが多くなると、ブランチの切り替えの時間が長くなるからだ(何分もかかる)。」(Robert C. Martin「Clean Agile 基本に立ち戻れ」第6章より)
  • 注釈5
    「コードをすばやく捨てるために Git を使うなんて、開発者のリーナス・トーバルズも信じられないと思っているだろう。」(Robert C. Martin「Clean Agile 基本に立ち戻れ」第6章より)

参考文献

   

執筆

  • 和田 隆司(わだ たかし)

    富士通株式会社 FSTユニット
    ソフトウェア開発者、SPC(SAFe Program Consultant)、CSM(Certified ScrumMaster)

    2006年に業務掛け持ちの改善のために取り組み始めた「かんばん」、「リーン開発」をきっかけとし、Webアプリケーション開発業務を中心にアジャイル開発を実践。
    加えて現在は、新規ビジネス検証部門をはじめ、様々なチームの立ち上げにおけるアジャイル開発の技術支援にも従事している。

   

テクノロジーコラム一覧

ページの先頭へ


Subversion の場合
Git の場合1
Git の場合2
和田さん
メインビジュアル

世界のアジャイル動向を読み解く 前編 Agile
世界のアジャイル動向を読み解く 後編 Agile
アジャイル開発の士気管理 前編 Agile
アジャイル開発の士気管理 後編 Agile
アジャイル開発の進捗管理 前編 Agile
アジャイル開発の進捗管理 後編 Agile
アジャイル開発の進捗管理 番外編 Agile
アジャイル開発の原価管理 前編 Agile
アジャイル開発の原価管理 中編 Agile
アジャイル開発の原価管理 後編 Agile
大規模アジャイル開発の可能性 前編 Agile
大規模アジャイル開発の可能性 後編 Agile
大規模アジャイル開発の可能性 番外編 Agile
アジャイル開発の品質管理技法 前編 Agile
アジャイル開発の品質管理技法 中編 Agile
アジャイル開発の品質管理技法 後編 Agile
アジャイル開発とは 前編 Agile
アジャイル開発とは 中編 Agile
アジャイル開発とは 後編 Agile
デジタル技術を活かした人流カウントと勘所 dx
アジャイル開発の士気管理 前編 AgileとComing Soon
アジャイル開発の士気管理 後編 AgileとComing Soon
「アジャイルなら Git」の神話 Agile
「アジャイルなら Git」の神話 AgileとNEW