バージョン管理（Git、TFVC）と管理サーバー（GitHub等）を選定する

# 概要

バージョン管理（Git、TFVC等）と管理サーバー（GitHub、Azure DevOps等）の選定について説明します。また、ブランチ戦略についても紹介しています。

気になる点などコメントお願いします。

- (1) バージョン管理の選択
	Git、TFVCなど
- (2) 管理サーバーの選択
	GitHub、Azure DevOps Servies、Azure DevOps Serverなど
	※Azure DevOps Serverは、Azure DevOps Servicesのオンプレミス版。旧名 Team Foundation Server(TFS)
- (A) 参考
	セキュリティに関する情報、バージョン管理システム間の単語の違い、ブランチ戦略など

# (1) バージョン管理の選択

バージョン管理を選択します。

バージョン管理には中央集権型（TFVC、Subversion）と分散型（Git）２つの方式があります。

## (1-1) 用語説明

先に用語について簡単に説明します。

|用語|説明|
|---|---|
|リポジトリ|フォルダ・ファイルの編集履歴（内容、更新者）、名称変更等を保存したデータ。|
|ブランチ（分岐）|稼働中のシステムでは、新規機能開発中でも不具合に対応する必要がある。<br>この対処法がブランチとなり、稼働中のシステムと新規機能を別で管理しながら、最終的に１つにする（マージ）ことができる。<br>※ブランチ戦略は(A-3)で説明。|
|マージ|ブランチから別のブランチに履歴も含めて変更を反映する。<br>同じファイルを編集してコンフリクト（衝突）した場合は手作業となる（[VSCodeなども利用可能](https://futureys.tokyo/lets-resolve-conflict-on-git-by-vs-code/)）。|

## (1-2) 中央集権型と分散型の違い

### (1-2-1) 中央集権型（TFVC、Subversionなど）

リポジトリをサーバーに用意し、各開発者は基本的には常にサーバーに接続している必要があります。

各開発者は必要なファイルをローカルにダウンロードし、サーバーにチェックアウト（編集開始）を要求してから編集を行います。誰が編集しているかを容易に確認することができ、設定により他の人が編集できない（ロック）という運用も可能です。

またブランチとマージ運用も可能です（Gitほど柔軟ではありませんが、そのシンプルさは利点とも言えます）。TFVCでもブランチの作成は必須であり、Microsoftも[ガイドラインを公開](https://docs.microsoft.com/ja-jp/azure/devops/repos/tfvc/branching-strategies-with-tfvc?view=azure-devops)しています。

ソリューションの構成が1つの機能=1プロジェクトまたは1ファイルで担当者が明確な場合や、開発がメインではないメンバーが関わる場合は、シンプルで使いやすいと言えます。

TFVCは、Microsoftらしい合理的なバージョン管理システムと感じます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/9759d1bb-2ec3-11e6-4781-48ffea235cb3.png)

引用元：https://www.atmarkit.co.jp/ait/articles/1504/17/news023.html

### (1-2-2) 分散型（Git）

リポジトリをサーバー（リモート）に置くという点は中央集権型と同じです。

異なるのは各開発者がリポジトリを丸ごとローカルにコピーし、複製したリポジトリからソースコードを複製して編集を行います。

ブランチの作成を柔軟に行うことができます。ブランチ内で作業することで、同一のファイルを複数人で同時に細かく編集する必要があり複数の機能（バージョン）の変更を同時に進める大規模プロジェクトなどでも、他の修正に影響を与えることなく開発を行うことができます。

また開発者単位にローカルでリポジトリを持つため、サーバー（リモート）に変更を反映させるまではどのメンバーがどのファイルを編集しているかを知ることはできません。ローカルリポジトリの変更はプッシュするまではどこにもバックアップされていない点も含め、作業ブランチの作成ルール・プッシュタイミングなどルール作りが大事です。

Gitを使用するならば、ブランチを活用しなければGitを採用した意味はあまりありません。しかしGitのブランチとマージを活用するには教育とルール作りが必要であり、ルール無視で使うとソースの消失やマージミスが多発する危険性があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/c4a17ded-d711-593e-8c13-241096867e4e.png)

引用元：https://www.atmarkit.co.jp/ait/articles/1504/17/news023.html

## (1-3) ではどちらがおすすめなのか

では、中央集権型（TFVC、Subversion）と分散型（Git）どちらがおすすめなのでしょうか。

どちらにも利点があり、どちらが優位というものではありません。開発メンバー、プロジェクトの特性により状況は変わります。

ただし、最近の開発ではGitをベースとしたツール構成となっています。新規プロジェクトでは基本的にはGitを選択したほうが良いと思われます。例えば、Azure DevOps Services (Server）でも新規プロジェクト作成時はGitが既定値となっています。

以下にまとめます。

|開発状況|バージョン管理システム|タイプ|管理サーバー|
|---|---|---|---|
|・どちらかというとウォーターフォールなSI開発向き。<br>・**基本的には**既存プロジェクトで選択する。<br>・少数の開発担当者（実装者）で開発する現場。<br>・リリースするバージョンが多岐にわたらず、同時に編集できることがリスクとなる場合。|TFVC、SubVersion|リポジトリ中央集権型|TFVC:<br>Azure DevOps Services (Server）、<br>Subversion:<br>SVNサーバー|
|・どちらかというとアジャイルなサービス開発向き<br>・新規プロジェクト。<br>・外部組織に実装等を多く出している現場。<br>・開発の頻度が頻繁、またはリリースするバージョンが多岐にわたる。|Git|リポジトリ分散型|Azure DevOps Services (Server）、GitHub、GitLabなど|

# (2) 管理サーバーの選択

バージョン管理システムを選択したら、管理サーバーの検討となります。

管理サーバーにはクラウド、オンプレミス（自社に構築）大きく2つの方法があります。また、プルリクエスト・CI/CDなどの付加機能、リスクアセスメントも検討します。

💡 [クラウドとオンプレミス](https://www.kagoya.jp/howto/rentalserver/on-premises/)

## (2-1) 付加機能

バージョン管理システムの管理サーバーの役割以外の機能にも注目する必要があります。

例えば、有名なプルリクエスト（ブランチマージ前にレビューを行う）はGitの機能ではないため、単純なGitサーバーではプルリクエストを実現できません。

Azure DevOps Services (Server）、GitHub、そしてGitLabともに主な機能では大きな違いはなく、Issue（作業項目）ベースの開発、プルリクエスト、CI/CDを行うことができます。（プランにより可能なオプションは異なってきます。）

またAzure DevOps Services (Server）では、プロジェクトによりTFVC・Gitを選択することができ、TFVCを選択した場合も作業項目ベースの開発やCI/CDが可能です。

**各管理サーバーの価格・プラン**

- [GitHubの価格・プラン](https://github.co.jp/pricing.html)
- [Azure DevOps Services(Server)の価格・プラン](https://azure.microsoft.com/ja-jp/pricing/details/devops/azure-devops-services/)
	Visual Stuio サブスクリプション（旧 MSDN サブスクリプション）には[1つのサーバー ライセンスとユーザーCAL](https://azure.microsoft.com/ja-jp/pricing/details/devops/server/)が含まれます。
- [GitLabの価格・プラン](https://www.gitlab.jp/pricing/)

## (2-2) リスクアセスメント

会社で開発する場合はリスクアセスメント（権限管理、ログ収集・監査、教育、バックアップの検討調査）とリスク低減措置が必要です。クラウドの管理サーバーを利用して開発を行うのであれば、より強いリスク低減措置が求められます。

GitHubであれば、[規約](https://docs.github.com/ja/github/site-policy/github-terms-of-service#b-account-terms)からも有償版の契約は必須であり、求められるセキュリティレベルに応じてEnterprise版の検討も必要です。GitHubのEnterprise版であれば監査ログAPIの利用、IPアドレス制限を行えます。

GitHubで[Enterprise-Managed Users](https://github.com/github/roadmap/issues/132)のロードマップが公開されています。Enterprise-Managed Userでは、公開リポジトリは読み取り専用となり組織のリポジトリのみ更新できるという制限が行えるようです。

また、社内開発のみであれば、オンプレミスでの管理サーバー構築も検討してもよいかもしれません。

## (2-3) 対応するバージョン管理システム

Azure DevOps Services (Server）はTFVC、Gitに対応しています。ただしTFVCの機能強化はストップしています（TFVCでもコードレビューは可能ですがVisual Studio必須です）。

GitHubはGit以外にも[Subversionクライアントに対応している](https://docs.github.com/ja/github/importing-your-projects-to-github/support-for-subversion-clients)ようですが、制限事項の有無など詳細は未調査です。

## (2-4) ではどちらがおすすめなのか

では、クラウドとオンプレミスどちらがおすすめなのでしょうか。

どちらにも利点があり、どちらが優位というものではありません。組織の規模、セキュリティに関する考え、社内のライセンス状況（開発メンバーはVisual Stuio サブスクリプションを保持しているのでAzure DevOps Serverの利用に追加費用が不要、など）、将来的な展開などにより状況は変わります。

ただし基本的には、外部組織と継続的に開発するプロジェクトであればクラウドを検討し、社内で開発するプロジェクトであればオンプレミスを検討する、となるのではないでしょうか。

場合によっては、オンプレミスで構築したサーバーに外部からアクセスさせるという選択もあるかと思います（インフラ面の作業・対策が必要となりますが）。

以下にまとめます。

|開発形態|環境|管理サーバー|備考|
|---|---|---|---|---|
|外部組織と開発、<br>またはオンプレでサーバーを持ちたくない|クラウド|[GitHub](https://github.co.jp/)、[GitLab](https://www.gitlab.jp/pricing/#gitlab-com)、[Azure DevOps Services](https://azure.microsoft.com/ja-jp/services/devops/)など|・リスクアセスメントとして、権限管理、ログ収集、教育、定期的バックアップ、Single Sign-On (SSO)など。<br/>・GitHubなら有償契約が必要。
|社内で開発、<br>または規約等でクラウドにデータを置けない|オンプレミス|[Azure DevOps Server](https://azure.microsoft.com/ja-jp/services/devops/server/)、[GitLab](https://www.gitlab.jp/pricing/#self-managed)、[GitBucket](https://github.com/gitbucket/gitbucket)|・Azure DevOps Serverの権限管理にはAcitive Directoryが利用できる<br>・外部向けにAzure DevOps ServerやGitlabなどを公開する場合は、インフラ面の費用などが増加する<br>・Azure DevOps Serverについて、Visual Stuio サブスクリプション（旧 MSDN サブスクリプション）に[1つのサーバー ライセンスとユーザーCALが含まれている。](https://azure.microsoft.com/ja-jp/pricing/details/devops/server/)|

# (A) 参考

## (A-1) セキュリティに関する情報

- [GitHubのSAML single sign-on (SSO)機能](https://techblog.zozo.com/entry/github_sso)
- [Azure DevOps (Server)に関するセキュリティ情報](https://www.slideshare.net/kkamegawa/azure-devops-127875796)
- [GitHub利用規約](https://docs.github.com/ja/github/site-policy/github-terms-of-service#b-account-terms)
	- GitHub無料アカウントは1人で1つのみ
	- アカウントは共有できない（有料の「Organization」は、サブスクリプションが許可する数の「ユーザアカウント」に対してのみアクセスを提供）

## (A-2) バージョン管理システム間の用語の違い

作業に対するTFVCとGit間の用語の違いについてまとめます。

|作業|TFVC|Git|
|---|---|---|
|ブランチ作成|分岐<br>フォルダ単位で作成し[別フォルダとなりアイコンが変わる](https://black-techmemo.net/tfs/tfs2012/1251/)。<br>ブランチ元は管理サーバーが記録している|branch|
|ブランチの切り替え|なし<br>作成したブランチ（フォルダ）のファイルを編集すればよい|チェックアウト（checkout）<br>switch　※最近追加された|
|ブランチ間のマージ|マージ|マージ(merge)|
|編集開始|チェックアウト|なし|
|サーバーのリポジトリに変更を反映|チェックイン|なし|
|ローカルのリポジトリに変更を反映|なし|コミット（commit)|
|リモートリポジトリの変更内容の確認<br>（リモート追跡ブランチに取得、ローカルブランチは変更されない）|なし|フェッチ（fetch)|
|リモートリポジトリの変更をローカルリポジトリの作業中のブランチに反映|なし|プル（pull)|
|ローカルリポジトリの作業中のブランチの変更をリモートリポジトリに反映|なし|プッシュ（push)|

## (A-3) ブランチ戦略

いくつかのブランチ戦略について紹介（引用）します。

### (A-3-1) MAIN、DEVELOPMENT、RELEASE

> チームは、スプリントの最後にコードをリリースできるはずです。Team Foundation Server を使用すると、特定の時点でコードのスナップショットを取得するようにブランチにラベルを付けることができます。次の図に示すように、リリースの MAIN ブランチにラベルを付けることができます。これにより、この時点でブランチをその状態に戻すことができます。
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/b0943e84-c51d-feda-0e06-797ef52a81fd.png)
> リリースに更新を実装する必要があるため、リリースのブランチを作成すると、チームは今後のリリースとの競合を発生させずに、次のスプリントで独立して作業を続けることができます。次の図は、更新プログラムのコードを含み、2 番目のスプリントの最後のリリース後に MAIN 分岐に逆に統合される分岐を示しています。
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/288f60e4-a93d-9733-b9e0-6b8594cd1d22.png)
> リリースのブランチを作成する場合は、最も安定した MAIN ブランチからそのブランチを作成する必要があります。作業ブランチからリリースするために分岐すると、作業ブランチの安定性が保証されないため、統合の問題が発生する可能性があります。

引用元：https://docs.microsoft.com/ja-jp/azure/devops/repos/tfvc/branch-strategically?view=azure-devops#how-does-the-team-manage-releases-from-the-version-control-perspective
参考：https://www.infoq.com/jp/news/2012/04/Branching-Guide/

### (A-3-2) GitHub Flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/3e9785d9-205a-0f8d-ace1-c647260730c5.png)
参照：https://guides.github.com/introduction/flow/

> - masterブランチは常に本番環境へデプロイ可能にする
> - 開発を始める際にはまずブランチを作成する(ブランチ名は内容を説明するようなものがよい)
> - 準備が整い次第できるだけ早くPull Requestを作成し、コラボレーションを始める
> 	- コードレビューやCIを実施しながらブランチにコミットを重ねていく
> - レビュー完了、CI通過、等々なんらかの基準を満たした後、当該ブランチをデプロイする
> 	- 問題が発生した場合にはmasterをデプロイし直す
> - デプロイ後問題なければ当該ブランチをmasterにマージし、当該ブランチを削除する

引用元：https://thinkit.co.jp/article/8410

### (A-3-3) GitFlow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/2da4823b-b106-cc15-9397-114773ea8a72.png)
参照：https://nvie.com/posts/a-successful-git-branching-model/

#### GitFlowを使用すべき組織、使用すべきではない組織

以下の記事を参考に整理しました。
https://itnews.org/news_contents/please-stop-recommending-git-flow

##### GitFlowを使用すべき者

- リリースサイクルが**毎月、または四半期**ごと。
- チームが複数のリリースと並行して作業している。
- チームが **20人以上** で並行してリリースに取り組んでいる。

→　チームを混乱させないように**十分**な儀式(ceremony)を提供し保証してくれる。

##### GitFlowを使用すべきではない者

- **一日に複数**のリリースがある場合。
- チームがスタートアップである場合やインターネットに接続しているウェブサイトあるいはウェブアプリケーションに携わっている場合。
- チーム規模が小さい（**10人未満**）場合。

→　**過剰**な儀式(ceremony)となり、あまりに多くのオーバーヘッドが掛かる。

## (A-4) その他

- [Git と TFS との比較と使用感 | Remember The Time](https://www.remember-the-time.xyz/2015/01/git-tfs.html)
- [TFVC から Git への移行 - Azure DevOps | Microsoft Docs](https://docs.microsoft.com/ja-jp/devops/develop/git/migrate-from-tfvc-to-git)