2022年10月25日
【GitとSubversionの構造的な違い】GitのブランチはSubversionのブランチとは全く違うモノ~奥村 和彦 Kazuhiko Okumura
最近はVCS(バージョン管理システム)のデファクトスタンダードと言っても過言ではないGit(ギット)ですが、まだまだSubversion(サブバージョン)をご利用されているお客様も多く「Git(Bitbucket)に移行したいがSubversionとの違いやメリットがよくわからない。」と言ったご質問をいただくことがあります。
私自身もこれまでの職場ではSubversionもしくはCVSを利用していて、Gitは勉強用のスニペットコードで利用する程度でしたので同様の疑問を持っていたのですが、リックソフトでBitbucketに触れたことでGitとSubversionとの違いやGitの良さを実感することが出来ました。
そこで私が勉強した中でも特にGitを理解することに役立ちました。GitとSubversionの構造的な違いについてお話ししたいと思います。
今回のブログではGitコマンドの説明や使い方までは触れておりません。ですがGitコマンドをご理解する上できっとお役に立つ話だと思います。
世界10万社が使うプロジェクト管理ツール
\アジャイル開発チームの利用実績 No.1/
アジャイルプロジェクト管理ツールです。
ソースコード管理Gitツールの「BitBucket」と統合し、継続的デリバリーを実現させます
Gitは分散型バージョン管理システム(Distributed Version Control System)と呼ばれます。
その対比として、Subversionは集中型バージョン管理システム(Centrlized Version Control System)と呼ばれることもあります。
Subversionはサーバーにインストールした"リモートリポジトリ"だけが、ソースコードのバージョンを管理しています。
開発者はリモートリポジトリにアクセスして自分のローカルPCに指定したバージョンのソースコードをダウンロード[チェックアウト]して開発します。
修正や追加したソースコードはリモートリポジトリへ登録<コミット>します。
それに対してGitは開発者自身のローカルPCに"ローカルリポジトリ"を持ちます。
開発者はこのローカルリポジトリに修正や追加したソースコードをコミットするのがSubversionとの大きな違いです。
ローカルリポジトリはリモートリポジトリの完全なコピー["クローン"]として作成します。ローカルリポジトリにコミットしたソースコードは、リモートリポジトリに反映["プッシュ"]することでローカルリポジトリとリモートリポジトリの内容を同じに合わせます。個々のローカルPCにもリポジトリを構築するので分散型と呼ばれています。
分散型バージョン管理は集中型と比べて次のようなメリットがあります。
ローカルリポジトリでソースコードを管理するので「ブランチを切り替える」「コミットする」「差分を比較する」「マージする」といった操作の度にリモートリポジトリアクセスする必要がありません。
(※リモートリポジトリとは定期的に通信して最新情報を取得しておく必要はありますが。)
ローカルリポジトリは自分専用のリポジトリとなるので、ちょっとしたことを試したいときに気軽にブランチを作成してコミットすることができます。作成したブランチやコミットはマージするときに新しいコミットにまとめること[squash]ができますので、ちょっとしたブランチやコミットを正式な"開発コミット"に整えてからリモートリポジトリにプッシュできます。
リモートリポジトリとローカルリポジトリは完全なコピーですので、リモートリポジトリに障害が発生してもローカルリポジトリから復元することができます。
(※復元する元のローカルリポジトリに最新情報が取り込まれている["フェッチ"]場合に限りますが。)
リモートリポジトリから別のリモートリポジトリをコピー["フォーク"]した場合、ローカルリポジトリはフォーク元とフォーク先の両方のリモートリポジトリとアクセスして同期することができます。これを利用すると例えば、あるパッケージ製品のリポジトリからお客様向けにカスタマイズしたリポジトリをフォークした場合、ローカルリポジトリでコミットしたパッケージのバグ修正や機能開発をパッケージリポジトリとカスタマイズリポジトリの両方へプッシュでき、フォーク元とフォーク先のリポジトリの共通部分を同期させることができます。
分散型であるGitに移行してもコミットやマージはSubversionと同じ感覚で使うことができます。また新たにプッシュやフェッチ、プルといった操作が追加されますが、分散型リポジトリの仕組みを理解することでそれほど難しい操作でないことは感じ取っていただけると思います。
世界10万社が使うプロジェクト管理ツール
\アジャイル開発チームの利用実績 No.1/
アジャイルプロジェクト管理ツールです。
ソースコード管理Gitツールの「BitBucket」と統合し、継続的デリバリーを実現させます
SubversionとGitの大きな違いはブランチ管理あると私は考えています。最近のソースコードのバージョン管理では、機能開発やバグ修正の専用ブランチを作ってリリース用ブランチへマージする開発スタイルが主流になってきており、開発プロジェクトにおいてコードのブランチ管理は必要不可欠であると言えます。ですがSubversionのブランチ管理はとても難しいため、次のような経験があるユーザーも多いのではないでしょうか?
これはSubversionの変更管理方法がファイルごとに変更履歴を管理していることに起因します。ある時点から現在までの変更内容を抽出するには期間内の変更履歴を順番に追跡する必要があります。またSubversionのブランチは単なるコピーです。しかしコピーした後は同期しないため、変更履歴はコピー元とコピー先で異なり、マージするときはそれぞれの変更履歴を追跡しながら処理しなければなりません。もちろんSubversionでこの処理を最適化するような仕組みはありますが処理としては少し複雑な感じがします。
ここからSubversionは差分比較に弱いためマージやコンフリクトに掛かるコストが高く、ブランチ運用が難しいことがお分かりいただけると思います。
その点GitはSubversionとは真逆と言っても過言では無いほど異なるアプローチでブランチを管理します。ポイントは2つです。
Gitはコミット単位に変更履歴を管理しています。コミットを行うと次のような情報を登録します。
このコミット情報により2つのコミット間の差分はスナップショット同士を比較するだけで済みます。
どれだけコミット数が多くなっても、複雑になっても比較対象のコミット同士だけで、差分の比較が出来て、コンフリクトの箇所やマージする部分が容易に特定できます。
また一つ前のリビジョンIDによってリポジトリ内の全てのコミットをツリーで表現してコミット履歴を追跡することができます。
リモートリポジトリからクローンしたローカルリポジトリはコミット情報の内容や構造も全て同じな完全なコピーです。
クローンした後もリモートリポジトリとローカルリポジトリ間の同期(プッシュやフェッチ、プルなど)によって同じ情報を維持します。
これによって複数ユーザーが個々のローカルリポジトリで行ったコミットであってもリモートリポジトリを通して共有化されますので、コンフリクトの解消やマージ処理が簡単に実施できるようになっています。
本題のGitのブランチですがここまでの説明でピンっと来た方もいるかもしれませんが、コミット情報がそのまま"ブランチ"として扱われます。なぜならGitのコミット情報は「その時点の全ファイルの情報スナップショット」を持っているためで、Gitのブランチは膨大なコミットの中から、ある一つのコミットに目印を付けているのです。
以下の表は、Gitブランチに対する操作イメージです。
Gitブランチの操作
|
行っていることのイメージ
|
---|---|
作成 | 最新コミット情報に目印をつける |
コミット | コミット情報を作成して目印を移動する |
マージ |
コミット情報間のファイルをマージして、新しいコミット情報を造りそこに目印を移動する。 |
削除 | コミット情報から目印を無くすこと(コミット情報は削除しない) |
Gitのブランチは差分比較に強くマージやコンフリクトに掛かるコストも低いことがお分かりいただけるでしょうか。Gitのブランチは変幻自在なのです。
Gitは「分散型リポジトリ」や「コミットの変更履歴を活用したブランチ」といったSubversionとは全く異なる発想で作られたバージョン管理システムです。その仕組みは、現在のアジャイル開発やDevOpsといった高い生産性が求められる開発フローにとても合っていると思います。
Gitのようにツールを導入する際には学習コストも掛かるのですが、今回説明したGitの構造およびSubversionとの違いをご理解いただければ少しでもスムーズな切り替えを可能にすると考えています。特にGitの`branch`,`rebase`,'merge(Fast-Forward/Mergeコミット/squash)'と言ったコマンドを理解するのに役立てられると思います。
最後にGitのホスティングサービス、AtlassianのBitbucketをご紹介させてください。
Gitのホスティングサービスとは、リモートリポジトリを管理するWebアプリケーションです。Gitはコマンド(CUI)を使って操作しますが、これをWeb画面のGUIで操作することができます。その他にもホスティングサービスごとに特有のGitの拡張機能を搭載します。Gitホスティングサービスの代表的な製品と言えばGitHubだと思いますが、BitbucketもGitHubと同等の機能やAtlassian製品ならではの機能があります。
今回はオンプレミス用のBitbucket Severの特徴について紹介します。
リモートリポジトリ内のソースコードを確認したり、コミット履歴から変更内容や差分情報を画面で確認できます。また、ユーザーのプロフィールや権限の管理、リポジトリやブランチのアクセス権限の設定などをグラフィカルなインターフェースを通して操作できるため、Gitの管理が容易になります。
コミット情報にステップ単位でコメントを入力し、チームのコードレビューやコミュニケーションを記録することができます。
開発用に作成したブランチのコードを元のブランチにマージするためのレビューと承認依頼が行える、プルリクエスト(プルリク)が利用できます。プルリクを利用することでmainブランチなどの本番用開発コードへ、不用意にマージされることを防ぐことができます。
またプルリクエスト承認後のブランチのマージ戦略(Mergeコミット/Fast-Forward/Squash/Rebase)やgit-flowに従ったブランチ戦略の設定も行えるのはBitbucketの特徴の一つです。
BitbucketはJiraやBambooといったAtlassian製品と連携することで強力なアプリケーション連携機能を利用することができます。
更にBitbucket DataCenterであればアクティブ-アクティブクラスタリングやスマートミラーリングによる耐障害性や可用性、信頼性を向上させることもできます。
Subversion(あるいはCVS)と比較し、GitおよびGitのホスティングサービスを導入することで、開発の効率化やスピードアップおよび生産性向上が期待できそうに感じていただけたでしょうか?
特にソースコードのマージ処理では、Gitの分散型リポジトリやブランチ管理によってコンフリクトの発生自体を減らしたり、コンフリクトを解消する作業が簡単になると思います。
Git自体はフリーで利用できますが、リポジトリの運用管理やプルリクエストと言ったコードの品質を上げるための拡張機能を持つGitホスティングサービスを導入することで更に開発効率が上がりますし、開発も楽しくなると思います。
この分野ではGitHubが有力なツールだとは思いますが、セキュリティポリシーや運用ルールの制約がありプライベートクラウドでGitを利用する必要があったり、AtlassianのJiraとの連携をお考えでしたら、Bitbucket がオススメです。
BitbucketでのGitの導入をお考えでしたら、お気軽にリックソフトにご相談ください。
---この記事は2018年11月07日に執筆したものを2022年10月25日に再編集したものです。---
あわせて読みたい!
★プロジェクト成功の鍵を握る「見える化」|
プロジェクト管理における見える化のメリットや作業のステップを解説
★スムーズなプロジェクト進行に必要な工数管理のステップとは?
工数管理ツールを導入するメリットも解説
★2030年までに約80万人不足するIT・DX人材|
求められる役割や能力、必要な人材を確保する方法を解説
★システムの内製化のメリット・デメリットや実現に向けてのポイントを解説
★DX推進で注目されるアジャイル開発とは?
DXとの親和性が高い理由や取り組む際の課題と解決策を解説
本情報はブログを公開した時点の情報となります。
ご不明な点はお問い合わせください。
« サポート期限終了後もサーバー版のJiraを使い続けたらどうなるの?りっくまからのお手紙(2022年10月24日)
(2022年10月28日)クラウド版Confluenceでもデザイン性の高いページを作るアプリ紹介"Macro Suite" »
アトラシアン社ではサポート範囲外となっているサードパーティ製のアドオンをリックソフトのサポートではサポートします。
リックソフトのサポートは開発元が提供するサポート以上の価値があります。
ツールを導入しただけでは成功とはいえません。利用者が効果を感じていただくことが大切です。独自で制作した各種ガイドブックはツール活用を促進します。
リックソフトからライセンス購入を頂いたお客様にはガイドブックを無料進呈いたします。
ツール操作の研修だけでなく「ウォータフォール型開発」「アジャイル型開発」のシミュレーション研修も提供。
日本随一の生産性向上にも効果のある研修サービスです。
リックソフトからライセンス購入を頂いたお客様には無料招待や割引特典がございます。