今回はWebアプリ開発を効率よく行う上で不可欠となる「バージョン管理ツールGit」について紹介します。
本記事では以下について、初心者がBlazorアプリ開発においてGitを使う上で必要な最小限のことに絞って解説したいと思います。
- なぜバージョン管理ツールが必要になるのか?
- Gitの導入方法と基本的なコマンドの使い方
- Webアプリ開発におけるGit活用(管理対象外ファイル指定の重要性)
この記事を読むことで、Blazorアプリ開発においてGitを活用でき、その恩恵を感じられるようになるかと思います。
Gitには様々な機能があり、最初から全て覚えようとしても難しいです。
まずは基本的な操作を覚えて、自身の開発のなかで少しずつ活用しながら、ステップアップしていきましょう!
YouTubeの動画でも説明しています。
講義:なぜバージョン管理ツールが必要か?
バージョン管理ツールはアプリ開発において非常に重要な役割を果たします。
バージョン管理を行わずにアプリ開発を行うと以下のような問題が発生するでしょう。
アプリの規模が大きければソースコードのファイル数は多く、チーム開発ならば様々な人がそれらのファイルを修正するため、このような問題は深刻化します。
手動でバージョンを適切に管理するには多大な労力がかかるため、バージョン管理ツールを使って管理を自動化することが不可欠です。
バージョン管理ツールを導入することで煩雑な管理をツールに任せ、効率よくバージョン管理できます。
バージョン管理ツールは以下を自動で行ってくれます。
- 全バージョンの効率的な保持
- 任意のバージョンを復元
- バージョンの分岐やマージを管理
これで上述したような問題に悩まされなくなるわけですね。
バージョン管理ツールは、内部的には各ファイルの「差分」のみを管理・保持することで、効率よく全バージョンの管理をしています。
バージョン管理ツールはいくつかあるのですが、そのデファクトスタンダードといえるツールがGitです。
以降の演習では、アプリ開発でどのようにGitを使ってバージョン管理していくかを説明します。
演習1:Gitを導入して基本的なコマンドを使う
Gitを導入して基本的なコマンドを使ってみます。環境はWindows11を想定しています。
以下の手順で進めます。
- Gitをインストールする
- 簡単な例でGitの基本操作を学ぶ
Gitをインストールする
Git公式サイトでWindows版のGitをダウンロードします。
「Download for Windows」を選択しましょう。
ここでは、「64-bit Git for Windows Setups.」を選びます。
インストーラを起動するとオプションの選択画面がいくつも出るかと思いますが、全てデフォルト設定のままで進めて問題ありません。
インストール完了後に以下の画面がでるはずです。これでインストール完了です。「Finish」を押しましょう。
シェル(PowerShell等)を起動し、以下のコマンドを入力してみましょう。
git --version
以下のように表示されれば正常にインストールされています。
これでGitのインストールは完了ですね!
簡単な例でGitの基本操作を学ぶ
簡単な例を題材としてGitの操作を行いながら、Gitにおける基本的な用語や概念を学んでいきましょう。
以下の手順で進めます。
- 手順1:新規リポジトリを作成
- 手順2:ユーザ情報を設定
- 手順3:変更をリポジトリへ記録
- 手順4:特定のバージョンを復元
- 手順5:並行に行われた変更をマージ
手順1:新規リポジトリ作成
練習用にgittestという空のフォルダを作り、PowerShellでgittestフォルダへ移動します。
最初に以下のコマンドでgitのデフォルトブランチ名をmainにしておきましょう。
git config --global init.defaultBranch main
Gitのデフォルトブランチ名はmasterかmainです。(Gitのバージョン等により異なるようです。)
現在はmainとすることが公式に奨励されているため、mainとなるよう設定しています。
次に以下のようにgit initコマンドを実行するとGitリポジトリが作成されます。
git init
「リポジトリ」とは、Gitで管理されるファイルとその変更履歴等が保存されているデータベースのような場所です。
gittestフォルダは以下のように「.git」というフォルダが新しくできています。ここにはリポジトリ管理用の情報が格納されています。
これで、gittestフォルダ配下でGitによるバージョン管理ができるようになりました。
Windowsの初期設定では「.git」のようなドットで始まるフォルダやファイルは隠しファイルとして扱われ表示されませんので設定変更しましょう。
以下のように「…>オプション」を選びフォルダオプション画面を開き、「表示タブ」の「ファイルおよびフォルダー/ファイルとフォルダーの表示」で設定できます。
手順2:ユーザ情報を設定
リポジトリへ変更を記録する際の署名情報(名前とメールアドレス)を設定します。
git config user.name "プロ太"
git config user.email "prota@example.com"
誰が変更したかを記録するための情報となります。
リポジトリをGitHub等で公開すると、ここで設定した名前・メールアドレスも変更履歴の一部として公開されるため注意しましょう。
手順3:変更をリポジトリへ記録
以下のように書かれたテキストファイル「hello.txt」をメモ帳等で作成してgittestフォルダへ保存しましょう。
Hello World!
gittestフォルダ配下でリポジトリ(.gitフォルダ)を除いた部分を「作業ディレクトリ」と呼びます。
以下のようなイメージです。
作業ディレクトリでコーディングなど実際の作業を行い、必要に応じてリポジトリへアクセスして変更を記録したり、特定のバージョンを復元したりします。
今、リポジトリには何も記録されておらず、作業ディレクトリには「hello.txt」だけある状態です。
この作業ディレクトリの状態を最初のバージョンとしてリポジトリへ記録してみましょう。
次のように追加します。
git add hello.txt
git commit -m "hello.txtを追加"
リポジトリへ記録する対象のファイルをgit addで指定すると、ステージング領域へ追加されます。今回は1つですが、もちろん複数追加することも可能です。
そして、git commitコマンドによりステージング領域に登録した変更内容をリポジトリへ登録します。これをコミットするといいます。
-m “…”の部分は変更内容のメモ(コミットメーセージ)です。
Gitではコミットしたあるバージョン(フォルダ・ファイルのスナップショット)をコミットと呼びます。
次のようなイメージです。
ステージング領域は「ショッピングサイトのカート」みたいなものです。
リポジトリへの記録対象をステージング領域に登録しておき、それらをひとまとめにコミットするのです。
変更内容を一気にステージング領域へ登録したい場合には「git add .」とするとよいです。
コマンドを実行したフォルダ配下(サブフォルダ含む)の変更内容全てをステージング領域へ一括登録できます。
今、リポジトリにはコミットが1つある状態です。
hello.txtの中身を「Hello World!」から「Hello」へ修正して、それをコミットしてみましょう。
hello.txtファイル修正後に以下のコマンドを実行します。
git add hello.txt
git commit -m "hello.txtの文言を修正"
これでリポジトリには2つのコミットが記録され、以下のような状態になっています。
手順4:特定のバージョンを復元
リポジトリから過去のバージョン(コミット)を作業ディレクトリへ復元してみましょう。
過去のコミットを復元するためには、Gitのブランチ、HEAD、チェックアウトという概念を理解する必要があります。それぞれ以下のようになります。
- ブランチ:特定のコミットを指すポインタ
- HEAD:作業ディレクトリの変更を保存する先のコミット
(現在選択しているブランチが指すコミットを指す特殊なポインタ) - チェックアウト:特定のブランチへの切り替え
今のgittestフォルダを例にすると、以下のようになっています。
リポジトリを新規作成するとmainブランチが作成され、mainブランチへチェックアウトした状態になっています。
過去のコミット(上の図のCommit1)を復元するには、Commit1を指す新規ブランチを作成し、その新規ブランチをチェックアウトします。
まずgit logコマンドを実行してmainブランチの全コミット履歴を表示し、対象となるコミットのIDを確認します。
git log
次のように出力されます。新しいコミットから順に並んでいます。
PS C:\data\gittest> git log
commit f55b57468893c97203e12b3e32f13a850cfadf94 (HEAD -> main)
Author: プロ太 <prota@example.com>
Date: Mon Feb 5 21:19:27 2024 +0900
hello.txtの文言を修正
commit 9cf4a8238c7bda39760c808fa0efe45e79650e7a
Author: プロ太 <prota@example.com>
Date: Mon Feb 5 21:18:58 2024 +0900
hello.txtを追加
それぞれのコミットで、「commit 9cf4a82…」といった文字列がありますね。これがコミットIDです。
git checkoutコマンドで対象コミットを指す新しいブランチ(something-taskという名前にします)を作成し、その新規ブランチをチェックアウトしましょう。
コミットID部分は自分の環境で表示される「hello.txtを追加」に対応するコミットIDに置き換えて実行してください。
git checkout -b something-task 「hello.txtを追加」に対応するコミットID
以下のようにsomething-taskブランチへ切り替わり、作業ディレクトリはsomething-taskが指すコミットのスナップショットへ復元されます。
PS C:\data\gittest> git checkout -b something-task 「hello.txtを追加」に対応するコミットID
Switched to a new branch 'something-task'
test.txtファイルを確認すると「Hello World!」に復元されているはずです。
以下の状態になっています。
これで過去バージョンを復元できましたね!
手順5:並行に行われた変更をマージ
この過去バージョン(Commit1)を起点として、「Googbye!」と書かれたgoodbye.txtファイルを新規追加し、以下のようにコミットしてみましょう。
git add goodbye.txt
git commit -m "goodbye.txtを追加"
Commit1を基準として変更内容が保存され、以下のようにコミットの時系列が分岐し、Commit2と並行してCommit2’ができます。
歴史が途中で分岐しているイメージですね。
ブランチは世界線と考えるとわかりやすいかもしれません。
チェックアウトは別の世界線への移動となりますね。
開発を行っていると、何かの修正(例:Commit2の修正)によってプログラムが正しく動作しなくなることもありえますね。
そのようなとき、いったん正常に動作していた過去の状態(Commit1)へ戻したり、正常動作している状態を起点とした別の実装を試してみたり(Commit2′)できるわけです。
次にmainブランチへsomething-taskブランチをマージしてみましょう。
mainブランチへチェックアウトし、マージ対象となるsomething-taskをmergeコマンドで取り込んでマージします。
以下のコマンドを実行しましょう。
git checkout main
git merge something-task
以下のようにそれぞれの変更内容がマージされたCommit3ができます。
分岐していた歴史が1つに統合されました!
この仕組みで複数の人が並行した別々の編集内容をマージすることも可能となります。
Gitを複数人で使う場合は、リモートリポジトリの仕組みを使います。
人気のリモートリポジトリサービスとしてはGitHubなどがありますね。
GitHubとの連携方法についてはまた別の記事で解説したいと思います。
最後にリポジトリのコミット履歴や内容を確認する方法を紹介します。
以下のコマンドを実行してみてください。
git log --all --graph
以下のように全てのブランチとコミット履歴がグラフとして表示され、誰がいつどのような変更をしたのか変更履歴の全体を確認できます。
git diffコマンドで指定したブランチやコミット間の差分を表示することも可能です。
例えばmainブランチとsomething-taskブランチの差分を表示する以下のコマンドを実行してみましょう。
git diff something-task main
以下のように出力されます。
Gitが変更履歴をきちんと構造化して管理していますね!
差分の確認については、GitHubなどGUIで視認性良く確認できるツールを併用するのもよいでしょう。
Gitはテキスト形式のファイル(ソースコード含む)を管理するのが得意です。(画像ファイルなどのバイナリファイルも扱うことは可能です)
差分表示の利便性、マージの容易さ、差分のみ効率よくリポジトリへ保存可能といった点でテキストファイル管理に優れているのです。
演習2:Blazorアプリ開発でGitを使う
Gitによるバージョン管理はプログラミングやアプリ開発を進めるうえで役立ちそうですね。
実際の開発でGitを使う場合、プロジェクトにおけるすべてのファイルをバージョン管理の対象にするわけではありません。
一部を「バージョン管理対象外」として扱うことも重要です。
Gitでバージョン管理する方法を学んでいるのに、「バージョン管理対象外ファイルの指定」が重要ってどういうこと?と思われるかもしれませんね。
BlazorアプリのプロジェクトをGitで管理する演習を通して学んでいきましょう。
演習1の内容を復習しつつ以下の順に行います。
- 手順1:Blazorアプリのプロジェクトのリポジトリを作成
- 手順2:バージョン管理対象外ファイルの指定(.gitignoreファイル作成)
- 手順3:コミットしてリポジトリへ記録
手順1:Blazorアプリプロジェクトのリポジトリを作成
Blazorプロジェクトのひな形を作成しましょう。
プロジェクトを配置するフォルダを作成し、PowerShell等でそのフォルダへ移動します。
そして以下のコマンドでBlazorサンプルアプリのプロジェクトを作成します。
dotnet new blazor -n BlazorApp -o BlazorApp -f net8.0 --interactivity Auto -au Individual --use-local-db false
Visual StudioのインストールやBlazorプロジェクト作成・ビルド・デバッグ等の基本については以下の記事を参考にしてください。
BlazorAppフォルダができているのでフォルダ内へ移動し、以下のコマンドでGitリポジトリを作成しましょう。
git init
BlazorAppフォルダは次のような状態になるはずです。
手順2:バージョン管理対象外ファイルの指定
BlazorApp.slnをVisual Studioで開きデバッグ用のバイナリをビルドしましょう。
(CTRL+SHIFT+Bキーでビルドできます。)
フォルダ構成は以下のようになっています。
├─BlazorApp
│ ├─bin (★(a1))
…省略…
│ ├─Data
│ │ └─Migrations
│ ├─obj (★(a2))
…省略…
│ ├─Properties
│ └─wwwroot
│ └─bootstrap
└─BlazorApp.Client
├─bin (★(b1))
…省略…
├─obj (★(b2))
…省略…
├─Pages
└─wwwroot
(a1),(a2),(b1),(b2)はそれぞれBlazorAppプロジェクト、BlazorApp.Clientプロジェクトのコードから生成される実行形式ファイル(バイナリ)を格納するフォルダです。
obj、binフォルダはビルド時の中間生成物・ビルド結果のバイナリなどが格納されます。このフォルダは以下のような理由から、バージョン管理対象に含めるべきではありません。
- 冗長性: バイナリはソースコードをビルドすれば得られるため、バイナリまでバージョン管理するのは冗長
- ファイルサイズ:
bin・obj
のファイルサイズは大きく、これらをGitリポジトリに含めるとリポジトリサイズが肥大化 - 本質的でない差異の発生:Diffでバイナリファイル同士の差異まで検出
「ソースコードとバイナリ」の関係は「レシピと料理」のようなものです。
料理人(開発者)からすると…
きちんと管理・共有すべきはレシピ(ソースコード)です。
料理(バイナリ)はそれぞれの環境でレシピに基づいて一時的に作られるものです。
以下のようにソースコードをバージョン管理し、バイナリはそれぞれのバージョンのソースコードからビルドして生成します。
バイナリをエンドユーザ向けに配布する場合、通常ソースコードとは別の方法でバージョン管理します。
例えばGitHubならばコードのリポジトリとは別に「リリース機能」というバイナリを管理する仕組みが提供されています。
この他に、バージョン管理の対象外になるファイルとしては以下のようなものがあります。
- 機密情報(APIキー等)を含む環境設定ファイル(例:.env、appsettings.json)
- ログファイルや一時ファイル(例:*.log、*.tmp)
- 特定のユーザや環境固有のファイル(例:.vsフォルダ)
機密情報をバージョン管理対象に含めてしまい、GitHub等で誤って公開して漏洩してしまわないよう注意が必要です。
バージョン管理対象外は「.gitignore」というファイルを作成して指定できます。
.gitフォルダがあるフォルダ(BlazorApp)で以下のコマンドを実行すると、C#開発で一般的に管理対象外とするファイルが記述されたひな型を簡単に作成できます。
dotnet new gitignore
すると、以下のように.gitignoreファイルが生成されます。
.gitignoreの中身をみてみましょう。Visual Studio等で開けます。
中身を一部抜粋します。
…
.env
…
[Bb]in/
[Oo]bj/
…
.vs/
…
*.log
…
「[Bb]in/」というのはbinもしくはBinという意味になります。
バイナリが格納されるbin/objフォルダや、個人設定ファイル用の.vsフォルダなどが書かれていますね。
.gitignoreファイルが置かれたフォルダ配下の全てのフォルダ・ファイルについて、.gitignoreに記載されたファイルは管理対象外となります。
管理対象外となったファイルはコミットをしてもリポジトリへは記録されません。
基本的にはこの.gitignoreファイルをベースにして、必要に応じて管理対象外のファイルを追加すればよいでしょう。
手順3:コミットしてリポジトリへ記録
以下の手順でリポジトリへのコミットを行いましょう。
ファイルを一括してステージング領域へ登録するときは「git add .」ですね。
git add .
git commit -m "サンプルプロジェクトと.gitignoreファイル"
git addを実行すると以下のような警告が表示される場合があります。
PS D:\BlazorPJ2\BlazorApp> git add .
warning: in the working copy of 'BlazorApp/wwwroot/bootstrap/bootstrap.min.css', LF will be replaced by CRLF the next time Git touches it
Gitがリポジトリへの記録時に自動的に行末の改行コード(環境により異なる)を統一してくれているだけなので、気にしなくて大丈夫です。
「git ls-files」コマンドを使うと、管理対象ファイルでコミットしたものが表示されますので、実行してみましょう。
git ls-files
以下のように表示されます。
PS C:\data\BlazorApp> git ls-files
.gitignore
BlazorApp.Client/BlazorApp.Client.csproj
BlazorApp.Client/Pages/Auth.razor
BlazorApp.Client/Pages/Counter.razor
…
BlazorApp/Data/app.db
BlazorApp/Program.cs
BlazorApp/Properties/launchSettings.json
…
表示されたファイルの中にbin/objフォルダ配下含め.gitignoreで指定したものは含まれていないはずです。
参考ですが、Gitには以下の3つのファイル状態があります。「git ls-files」では①を表示しています。(②は含まれません)
- 追跡対象 (Tracked): 過去のコミットに含まれておりGitが変更を監視
- 非追跡 (Untracked): 作業ディレクトリで作成した新規ファイル
- 無視 (Ignored):
.gitignore
ファイルによってGitの追跡から除外
これでBlazorアプリ開発をGitでバージョン管理しながら行う基盤が整いました!
手順1~3のまとめ
ここまでの話をまとめると、Blazorアプリ開発でGitによるバージョン管理を行いながら開発を行う手順は以下のようになります。
プログラム修正/機能追加などを行ったときにこまめにリポジトリへの記録を行うことで以下のご利益を得られます。
- 変更により正常に動作しなくなった場合の原因調査
- コミット間の差分(どの部分を修正したか)を確認
プログラムへ何か少し変更を加えたらリポジトリへ記録することを習慣化できると良いですね!
まとめ
Webアプリ開発を行う上で必要不可欠な「バージョン管理ツールGit」を紹介しました。
アプリ開発におけるバージョン管理の必要性、そしてGitの導入方法と基本的な概念やコマンドの使い方を説明しました。
Webアプリ(Blazorアプリ)開発におけるGit活用方法についても紹介し、管理対象外ファイル指定の重要性と指定方法についても学びました。
Blazorアプリ開発初心者の方もぜひGitを使ってみてください。
変更により正常動作しなくなったときの原因調査などで「きちんと、バージョン管理しておいてよかった!」と思える場面があるかと思います。
引き続き、Webアプリ開発とBlazorを一緒に学んでいきましょう!