【Git】競合を起こさないためにできるGit以外のこと
はじめに
対象
- 競合解決でストレスを感じているITエンジニア向け。
競合が発生する人為的要因
競合が多発する現場を分けると、大きく2つのパターンがあります。
人為的要因:連携不足
一つ目は全く連携が取れていない場合です。各々好き勝手に開発を進めていて、互いに何をしているか把握していません。プルリクエストのマージは早いもの勝ちになってしまいます。大抵いつも競合解決するのは同じ人です。
コミュニケーションが取りづらい方だと進捗に影響が出ます。彼らを納得させる説明をした上で譲歩してもらうのは面倒なので、私の場合はその方面の方のプルリクエストがマージされるのを待ち、最新のmainにリベースしつつ競合解決してしまいます。
また周りを見ていないケースで、ほぼ全てのプルリクエストに影響が出るレベルの競合が出るリファクタリングをやらかした方もいます。この例はそもそもリファクタリングをする前に相談しろという話もあるのですが、案件対応中だったのでタイミングもかなり悪く大変でした。
人為的要因:競合しやすい計画
二つ目は開発計画や納期の都合で、複数人が同時に同じ箇所を修正せざるを得ない場合です。なるべく競合しないように開発者間で調整はするものの、完全に避けることは難しくなります。Excelで同時に同じセルを修正するようなものですからね。
もっとも元々の造りの問題で競合しやすいこともあります。フレームワークのルーティングなどは競合しやすいですが、競合解決の方法は確立されているので迷うことは少ないでしょう。適切にクラス設計がされていないものはリファクタリングしてください。
そもそも時間と修正箇所さえズラせればGitの競合は起きようがないので、あえて同時に修正せざるを得ないようなスケジュールを組むのが、そもそも非合理的です。この段階で競合するかは6割方決まっていると言ってもよいでしょう。
早い者勝ちの文化
これらの要因のある現場では、基本的に早い者勝ちの文化が発達します。
競合解決にはそれなりにスキルが必要です。先にマージした方がいい変更というのはケースバイケースで判断が必要ですし、競合自体の解決についても慣れが必要な作業ですし。もしGitに不慣れな方であれば、難易度の高いものはGit玄人にお願いしたいですし。
またコードだけでなくメンバーの事情も考慮しないといけません。各々の開発者の残タスクの量や、できること・できないことにもよります。できれば余裕のある方が進んで競合解決を買って出られるとよいのですが。
ここまでの説明でお分かりの通り、有無を言わさず早い者勝ちというのは、合理的でも効率的でもないんですね。競合解決に失敗するリスクもありますし、互いにストレスがかかることもあるので、あまり良い方針ではありません。何より現場がギスギスした空気に包まれます。
競合が起きない動き方
そもそも競合は「同時に複数の開発者が、同じ箇所を編集してしまう」のが原因なので、それを取り除いてやれば良い訳です。
開発計画と作業分担
開発計画を立てるときに、触る場所が重複しないように作業を割り振ります。この点からチームの采配を決定するリーダーや、開発計画を立てるマネージャーの役割は特に重要です。
機能の大きさにもよりますが、小中規模の機能追加程度なら1人で走りきってしまった方がいいでしょう。プルリクエストのレビューを依頼すれば、他の方に仕様やコードの説明をする機会がありますし、プルしたときに分からないことがあれば聞きますしね。
大規模な機能になってくると人数が増えてくるのですが、設計段階で人の動きまで読んでチケットを切れるか、でしょうか。前提となる設定やマスタなどの機能をフェイズ1、それらの設定を利用する各画面をフェイズ2として分けたときに、フェイズ2なら並行開発できるな、とか。
フェイズ1など1人でしか触れないところを先遣者に実装してもらっている間、他の開発者には競合しない別の作業を依頼しておきます。フェイズ2になったら合流して並行開発してもらえば、効率よく開発を行うことができます。
あとは「この機能改修ではソースコードのあの辺とあの辺を触ることになるだろう」という当たりが付くかどうかでしょうか。それが分からなければどこが競合するか分かりようがないですからね。業務のコードをどこまで詳細に把握しているかという話になってきます。
メンバー間の情報共有と連携
今誰が何を行っているかを可視化し、誰かの邪魔にならないよう配慮しながら動きます。
お互い分かっている開発者同士でなら、割と込み入った作業でもサクサク進みます。前の説明でフェイズ1として1人で行っていたような作業もある程度可能です。しかしできれば開発計画の段階で調整できるのがベターです。
例えばRailsで要員2名の場合、まずは作業ブランチを1本用意します。次に同時並行で、一人はテーブル・モデルを作り、もう一人はフロント側をモック状態で作る。声をかけ合って互いに必要なコミットをプッシュしていくということはしたことがあります。
またチケット駆動開発であれば、プロジェクト管理ツールを活用すれば良いです。担当者とステータスを変えるだけで、誰がどの辺を触るのか当たりが付き、不意打ちで競合することがなくなるだけでも違います。
朝会や夕会などのミーティングで話し合ってもいいですし、各自で判断できるのであれば競合しなさそうなチケットを取ればよいですから。その際、やはり現在の他のメンバーの作業や進捗状況にも留意する必要がありますが。
譲り合いの文化と合うか
あまり気持ちの良い話ではありませんが、譲り合いの文化を大事にしてコミュニケーションを取ろうとしてくれる方とでなければ、これらの施策は機能しません。現実的な現場の話をすると、自分本位に動いてしまう方は一定数観測されるのが現状です。
前述の通り仕組や譲歩で解決するのが望ましいですが、恐らくそういった方々は納得されず、ただ譲り合いの文化を持つ方だけがテイカーに搾取されるという構図になってしまいがちです。
なので採用時にチーム開発におけるGitの使い方を聞いて、きちんと連携して開発にあたれるかは確認した方がいいと考えています。もし自分が参画する側であれば、早い者勝ちの文化でないかは事前に確認した方がいいかもしれません。
Gitを理解する気があるというのが大前提としてあり、他の開発者にも配慮したコミュニケーションが取れるかが合わせて必要です。共有備品をルールを守って使うのは大前提として、長時間の占有や順番を譲ることができるかという話でして、それを仲良く使えないのはちょっと。
開発計画やマネジメントも同様で、Gitもコード側の事情も理解しようとしないで計画を立ててしまう方だとキツいです。考えなしにGitFeatureFlowをやって競合しまくっていたプロジェクトはかなり悲惨でしたね。
Gitがプロジェクトメンバー全員で使うものである以上、避けて通れない側面な上、全体である程度同じ方向を向かないといけないので、文化を作るというのも結構大変ですね。
その問題はGitが原因か
そもそもプルリクエストを出してマージするだけなら、そんなに高い技術力は必要ありません。チーム開発においてGitやGitHubを使う上で必要になるのは、各メンバーと都度コミュニケーションを取りながら開発を進められる連携力です。
今起きている問題が、Gitの技術的な知識の理解不足によるものなのか、それともGitの連携面での障害によるものなのか、まずはハッキリさせた方が良いと思います。
特にGit初心者はこれを混同しがちで判断も付きにくいので、困ったまま固まってしまうことが稀によくあります。連携面に問題がある場合、むしろ責任が大きいのは迎え入れた既存メンバーやチームの方なので、必要以上に自責の念に因われて萎縮して欲しくはないです。
なのでもし連携不足が原因でギスギスしているのであれば、今まで書いてきた方法を参考に、リーダーや賛同するメンバーを巻き込んで、効果的なやり方を模索していけばよいのではないかと。
おわりに
技術でゴリ押しせずに連携プレーをしていきましょう。
Discussion