Git とは? Google Cloud との連携
こんにちは!2024年度にクラウドエース株式会社に新卒入社しました、第二開発部の三浦です。
Git初心者のためのGitの解説
Gitとは?
Gitは、ソフトウェアの開発においてソースコードの変更履歴を管理するための分散バージョン管理システムです。
バージョン管理システムの基本
バージョン管理システム(Version Control System, VCS)は、プログラムやドキュメントの変更履歴を記録・管理するためのシステムです。特にソフトウェア開発で頻繁に使われており、以下のような機能や利点を提供します。
-
変更履歴の管理
各ファイルの変更履歴が保存され、誰が、いつ、どのような変更を行ったのかを正確に記録します。これにより、過去の状態に簡単に戻したり、変更の詳細を確認することができます。 -
共同作業のサポート
複数の開発者が同時に異なる場所や異なるタイミングで同じコードベースを編集できるようにします。変更のマージや競合の解決を容易に行うための仕組みがあります。 -
バックアップと復元
不測の事態でコードが失われても、過去のコミットや状態から簡単に復元できます。 -
ブランチ管理
機能開発やバグ修正のために、現在のコードベースから分岐した「ブランチ」を作成し、それぞれ独立して変更を進めることができます。これにより、新機能の開発と既存機能の保守が並行して行えます。
Gitの特徴と優位性
Gitは、その強力な機能と効率性から、世界中の多くの開発者に利用されています。以下に、Gitの特徴とそれが提供する優位性について詳しく解説します。
-
分散型リポジトリ
Gitの最大の特徴の一つは、分散型バージョン管理システムであるという点です。これは、全ての開発者がローカル環境に完全なリポジトリのコピーを持つことを意味します。この設計の利点は以下の通りです。- オフライン作業のサポート: インターネット接続が無くても、あらゆる履歴にアクセスし、ブランチを作成したりコミットすることができます。出張先やインターネット接続が不安定な環境でも作業を続けることが可能です。
- 安全性の向上: データの分散により、一部のリポジトリが破損しても他のコピーから復旧できるため、データの安全性が向上します。
-
高速性
Gitは設計思想として速度を重視しており、多くの操作を他のバージョン管理システムに比べて高速に実行できます。- 高速なコミットとブランチ操作: 意図した変更を迅速に反映したり、新たなブランチを素早く作成できるため、開発のスピードが向上します。
- ローカルでの操作の効率化: 大半の操作がローカルで行われるため、サーバーとの通信による遅延が発生せず、よりスムーズに作業が進められます。
-
軽量なブランチ操作
Gitでは、ブランチの作成、切り替えが非常に軽量かつ高速です。これにより、以下のような利点があります。- 実験的開発の促進: 開発者はリスクを恐れず新機能を試しやすくなり、失敗を恐れずに様々なアプローチを試行できます。
- 並行開発の簡略化: チームメンバーがそれぞれ異なる機能を独自のブランチで開発できるため、プロジェクトの進行が迅速かつ効率的に行われます。
-
強力なマージ機能
Gitは複数の開発者の作業を統合する際、多彩で強力なマージ機能を提供します。- 高度なマージアルゴリズム: 複雑なマージを行う際にも、競合を可能な限り最小化し、開発者に対して直感的に解決策を提示します。
- チームコラボレーションの支援: 開発者が異なるブランチで独立して作業した後、それらを統合する際の摩擦を軽減し、コミュニケーションの負担を減らします。
Gitのインストール方法
-
Windows
ダウンロード: Git公式サイト からインストーラーをダウンロードします。
インストール: インストーラーを実行し、画面の指示に従ってインストールを進めます。
確認: コマンドプロンプトまたは Git Bash を開き、git --version
でインストールを確認します。
-
macOS
Homebrew 利用: ターミナルを開き、以下のコマンドを入力してインストールします。
brew install git
確認: ターミナルでgit --version
を入力し、インストールが成功したことを確認します。 -
Linux
Debian 系(Ubuntu など):
sudo apt update
sudo apt install git
Red Hat 系(Fedora, CentOS など):
sudo dnf install git
初期設定
ユーザー名とメールを設定し、コミット時に反映されるようにします。
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
※"Your Name"
と"you@example.com"
はご自身のユーザー名とメールアドレスを登録してください。
これでGitのインストールと初期設定が完了です。
Gitの基本操作
ここでは Git を使う上での基本操作となるコマンドや仕組みついていくつかご紹介いたします。
git init (ローカルリポジトリの作成)
このコマンドは、新しいリポジトリを作成するために使用されます。
-
リポジトリとは?
リポジトリ はプロジェクトのファイル、コード、ドキュメント、画像などを格納し、それらの変更履歴を管理するための仕組みです。バージョン管理をすることで、特定の時点に戻ったり、変更内容を確認したりすることが可能になります。 -
基本的な使い方
コマンドを実行する前にターミナルやコマンドプロンプトを開き、リポジトリを作成したいディレクトリに移動します。
その後、以下のコマンドを入力します。
$ git init
-
実行結果
コマンドを実行すると、カレントディレクトリ内に.git
という名前の隠しフォルダが生成されます。 -
リポジトリタイプ
git init
コマンドは空のリポジトリを作成しますが、すでにファイルが存在するディレクトリでも実行可能です。
既存のファイルをバージョン管理に追加する場合、以下の手順に従います。
1: git initを実行してリポジトリを作成。
2: 変更したいファイルをgit addでステージング。
3: git commitを使って初めてのコミットを行う。
git add (ファイルの変更を記録する)
ファイルを変更したり新たに作成した後、その変更をステージングエリアに追加するために使います。
-
ステージングエリアとは?
ステージングエリア はコミットする前に変更を一時的に保持するための領域です。
複数の変更を一度にコミットする際に、意図した変更だけを選択してからコミットすることが可能になります。これによりコミット履歴をより整理された状態で保つことができます。 - 基本的な使い方
-
特定のファイルをステージに追加する場合
これは特定のファイルをステージングエリアに追加します。
$ git add ファイル名
-
現在のディレクトリ以下のすべての変更をステージに追加する場合
カレントディレクトリとそのサブディレクトリ内の変更すべてがステージングエリアに追加されます。
$ git add .
-
特定のディレクトリ全体を追加する場合
これにより、指定したディレクトリ内のすべての変更がステージングエリアに追加されます。
$ git add ディレクトリ名/
git commit (ファイルの変更を記録する)
ステージングエリアに追加された変更をバージョン履歴として記録するための非常に重要なコマンドです。
この操作を通じて、プロジェクトの進捗状況や変更履歴を一貫して管理することが可能になります。
- 基本的な使い方
-
基本的なコミット
この形式では、-mオプションを使ってコミットメッセージを直接コマンドラインから入力します。
$ git commit -m "コミットメッセージ"
-
メッセージなしでエディタを開く
この場合デフォルトのテキストエディタが開かれ、そこでメッセージを編集できます。複数行にわたる詳細なメッセージを記入する際に便利です。
$ git commit
git log (変更履歴を見る)
Git リポジトリの変更履歴を確認するのに使用するコマンドです。
これによりコミットメッセージや変更のハッシュ、作者、日時などの情報を確認できます。
- 基本的な使い方
$ git log
- 特定のファイルの履歴を見る
$ git log ファイル名
- シンプルな履歴表示 より簡潔な形式で履歴を見る場合
$ git log --oneline
git checkout, git revert (変更を取り消す)
-
git checkout: ファイルの変更を取り消す場合や、ブランチを移動するために使用されます。新しいGitバージョンでは
git restore
やgit switch
を使用することが推奨されています。
特定のコミットを取り消す
$ git checkout -- ファイル名
-
git revert: 過去のコミットの変更を打ち消すためのコマンドです。これは履歴を保ちながら変更を取り消す際に使用されます。
特定のコミットを取り消す
$ git revert コミットハッシュ
ブランチの作成と切り替え (git branch, git checkout)
- ブランチとは?
ブランチとは、 プロジェクトのコードを別々に管理するための「枝分かれした道」のようなものです。これにより、異なる作業を同時に行えるようになります。
Gitなどのバージョン管理システムにおいて、開発の履歴を分岐させるための機能です。具体的には、ブランチを使うことで同じプロジェクトの中で複数の作業ラインを並行して進めることができます。
-
git branch: 新しいブランチを作成するためのコマンドです。ブランチを活用することで作業を並行して進めることができます。
新しいブランチを作成
$ git branch ブランチ名
-
git checkout: 作成したブランチに切り替えるために使用します。今後は
git switch
コマンドが推奨されています。
ブランチを切り替え
$ git checkout ブランチ名
ショートカットを使った新規ブランチ作成と切り替え(最新バージョンではgit switch
が推奨)
$ git checkout -b ブランチ名
git merge (ブランチのマージ)
-
マージとは?
マージとは 一般的に複数の異なるものを一つにまとめるプロセスを指します。
異なるブランチの変更を1つのブランチに統合するためのコマンドです。チーム開発での作業を統合する場合などに使用します。
特定のブランチを現在のブランチにマージ
$ git merge ブランチ名
リモートリポジトリの活用
-
ローカルリポジトリとは、 バージョン管理システムにおいて、ユーザーのPCやサーバー上などローカル環境に保存されているリポジトリのことを指します。
これは、リモートリポジトリ(GitHub、GitLab、Bitbucketなどにホストされているリポジトリ)と対照的な概念です。 -
リモートリポジトリとは、 ネットワーク上にホストされているリポジトリのことを指し、複数の開発者がアクセスしたり、変更を共有したりするために使用されます。
通常、リモートリポジトリは GitHub や GitLab、Bitbucket などのサービスを利用してオンライン上に保存されます。
GitHubアカウントの作成
- GitHubの公式サイトにアクセスします。
- ページ右上の「Sign Up」ボタンをクリックします。
- ユーザー名、メールアドレス、パスワードを入力し、指示に従ってアカウントを作成します。
- 確認メールが届きますので、メール内のリンクをクリックしてメールアドレスを確認します。
リモートリポジトリの作成
- GitHubにログインし、右上の「+」アイコンをクリックして「New repository」を選択します。
- リポジトリ名を入力し、必要に応じて説明文を追加します。
- 「Public」または「Private」を選択し、必要ならば初期化のためにREADMEファイルの追加を選びます。
- 「Create repository」ボタンをクリックします。
git remote add (ローカルリポジトリとリモートリポジトリの連携)
- 既にローカルリポジトリがある場合、ターミナルを開いてそのディレクトリに移動します。
- 以下のコマンドを実行してリモートリポジトリを追加します。
$ git remote add origin <リモートリポジトリのURL>
git push (リモートリポジトリへのプッシュ)
- 変更をコミットした後、以下のコマンドを実行してリモートリポジトリに変更を送信します。
$ git push origin <ブランチ名>
git pull (リモートリポジトリからのプル)
- リモートリポジトリから最新の変更を取得するために、以下のコマンドを実行します。
$ git pull origin <ブランチ名>
git clone (クローン)
- GitHub上のリモートリポジトリをクローンする場合、以下のコマンドを実行します。
これにより、リポジトリの内容がローカルにコピーされます。
$ git clone <リモートリポジトリのURL>
Git の注意点
ここでは Git を使う上でなにを気をつけた方がいいかについていくつかご紹介いたします。
誤ったブランチで作業
-
注意点
開発では複数人でのプロジェクトや異なる機能を並行して開発する際に、複数のブランチで作業を進めることが一般的です。
この際、意図したブランチとは異なるところで作業をしてしまうとその変更が想定外の機能やコードに影響を与える可能性があります。
特にチーム開発では大きな混乱を招くことがあるため、注意が必要です。 - 対処法
- 現在のブランチを確認する
$ git branch
-
変更を新しいブランチに移動する
まず、誤って作業を進めた変更を保存する新しいブランチを作成します。
$ git branch <新しいブランチ名>
-
元のブランチの変更を元に戻す
誤ったブランチに戻って、その変更をキャンセルします。作業を進める前のコミットに戻るには、git reset を使用します。
$ git checkout <誤ったブランチ名>
$ git reset --hard <前のコミットのハッシュ値>
- 正しいブランチで作業を続ける
$ git checkout <正しいブランチ名>
本番環境用のブランチに直接プッシュ
Gitでプッシュする際に、本番環境用のブランチ(一般的にはmainやmaster)に直接プッシュせずに、開発環境用のブランチを別で作成してそこで開発する方がいいです。
-
理由
安定性の確保: 本番環境用のブランチはプロダクトの安定した状態を保つ必要があります。直接プッシュしてしまうと未テストの変更がそのまま反映され、予期せぬバグや障害を引き起こすリスクがあります。
変更の管理: 直接プッシュすると誰がどのような変更を行ったのかが把握しにくくなります。特に大規模なチームにおいては、変更の追跡や責任の所在が不明確になる可能性があります。
レビューの欠如: 直接プッシュにより、コードレビューのプロセスが省略されることが多くなります。レビューはコードの品質を高め、バグを早期に発見するための重要なステップです。 -
対処法
ブランチ戦略の採用: 開発中の変更は、本番環境用のブランチではなく、機能ごとのブランチやトピックブランチで行うようにします。例えば、feature/new-featureやbugfix/issue123といった名前のブランチを作成して作業を行い、完成したら本番環境用のブランチにマージします。
プルリクエスト/ マージリクエストの利用: 新しいコードを本番環境ブランチに統合する前に、プルリクエストを作成してレビューを受けるようにします。これにより、他の開発者からのフィードバックを得られ、コードの品質を向上させることができます。
大事なファイルを誤って削除する
開発中に間違ってファイルを削除してしまうと、そのファイルに含まれていた重要なコードやデータが失われます。特にその削除がコミットされてしまうと、元に戻すのが困難になることがあります。
- 変更内容を確認する
$ git status
- ファイルを復元する
git checkout HEAD <復元したいファイル名>
Gitのコンフリクトが発生する
Git のコンフリクトは、同じファイルの同じ部分に対して複数の変更が加えられた際に発生します。
-
原因
並行しての作業: 複数の開発者が同じファイルを同時に編集し、異なるブランチでコミットすることが主な原因になります。
マージのタイミング: ブランチをマージする際に、その時までマージ元とマージ先のブランチで同じファイルの異なる部分が編集されている場合にコンフリクトが発生します。
再ベース: リベース時にも、コミットの変更を他のブランチの変更に適用するため、コンフリクトが発生することがあります。 - 対処法
-
コンフリクトの発見:
コンフリクトが発生すると、Gitはブランチのマージやリベースの最中にその旨を通知し、該当するファイルをリストアップします。 -
ファイルの編集:
コンフリクトしたファイルを開くと、通常は以下のようなマーカーで示されます。
<<<<<<< HEAD
あなたの変更
=======
他の人の変更
>>>>>>> ブランチ名
-
コンフリクトの解消:
必要な変更を手動で行い、コンフリクトマーカー<<<<<<<, =======, >>>>>>>
をすべて削除します。 -
解消済みのファイルをステージング:
解消したら、git add <解消したファイル>コマンドを使用してステージングします。 -
マージまたはリベースの完了:
コンフリクトが全て解消されたら、git merge --continue
やgit rebase --continue
を使って、マージやリベースを完了します。 -
テスト:
解決後は、コードベースが期待通り動作するかどうかをテストするのが良いです。
Git × Google Cloud
ここでは Git と Google Cloud をどのように連携して使用できるかの例を紹介します。
Git と Google Cloud の連携
Git と Google Cloud の連携では、Cloud Build を使用することが推奨されています。
現代のソフトウェア開発における継続的インテグレーション/デリバリー(CI/CD)パイプラインの構築において重要な役割を果たしています。
- 継続的インテグレーション(CI) は、頻繁にコードを統合し自動的にテストすることで早期にエラーを確認するプロセスです。
- 継続的デリバリー(CD) は、テスト済みの変更を安全にリリースできる状態に保ち、自動デプロイするプロセスです。
ビルドとは?
ビルドは、 ソースコードを実行可能なアプリケーション、ライブラリ、またはその他の成果物に変換するプロセスを指します。この過程では以下のことが行われることが一般的です。
- コンパイル: プログラミング言語のコード(例:Java、C++ など)を機械が理解できるバイナリコードに変換します。
- テスト: ビルドしたコードが意図した通り正しく動作するか確認します。ユニットテストや統合テストが含まれることが多いです。
- パッケージング: アプリケーションを配布可能な形式(例:WARファイル、JARファイル、Dockerイメージなど)にまとめます。
デプロイとは?
デプロイは、 ビルドされたアプリケーションやシステムを実際の運用環境に配置し、利用可能にするプロセスです。デプロイは一般的に次のステップを含みます。
- デリバリー: ビルド成果物をステージング環境や本番環境などに移動します。
- 設定および設定管理: 新しい環境に合わせてアプリケーションを設定します。これにはサーバーや環境変数の設定が含まれます。
- 運用開始: 利用者がアクセスできるようにして、必要に応じてモニタリングを開始します。
Cloud Buildのセットアップ
Google Cloud で CI/CD パイプラインを実現するには Cloud Build を利用します。Cloud Build は、コードの変更を検知して自動的にビルド、テスト、デプロイを実行してくれるサービスです。
- Cloud Build を利用することで、
- 開発の効率化: 手動でのビルドやデプロイ作業を自動化することで、開発者は開発作業に集中できます。
- ヒューマンエラーの削減: 自動化によって、手動作業によるミスを減らすことができます。
-
迅速なフィードバック: コードの変更をすぐにデプロイして確認できるため、問題点の早期発見・修正に繋がります。
といったメリットがあります。
Cloud Run は、コンテナ化されたアプリケーションをサーバーレスで実行できるサービスです。
- Cloud Run を利用することで、
- インフラストラクチャ管理不要: サーバーのプロビジョニングや管理、OS のアップデートなどを行う必要がなくなり、アプリケーション開発に集中できます。
- スケーラビリティ: トラフィックの増加に応じて自動的にスケールアップ/ダウンするため、常に最適なリソースでアプリケーションを実行できます。
-
コスト効率: リクエストが発生している間のみ課金されるため、無駄なコストを抑えられます。
といったメリットがあります。
Cloud Build と組み合わせることで、GitHub のコード変更をトリガーとした、ビルド、コンテナイメージの作成、Cloud Run へのデプロイまでを自動化できます。
ここでは、GitHub のコードを Cloud Build で自動的にビルドし、Cloud Run にデプロイする例を紹介します。
- 左側のナビゲーションメニューから「API とサービス」を選択し、「ライブラリ」をクリックします。
- 検索バーに「Cloud Build」と入力し、検索結果から「Cloud Build API」を選択し、有効化します。
- 「トリガー」タブに移動し、「トリガーを作成」ボタンをクリックします。
- 「リポジトリを選択」画面で「GitHub」か、利用するその他のリポジトリを選択します。
- OAuth を介して GitHub へのアクセスを承認し、Cloud Build がアクセスできるようにします。
※OAuth(Open Authorizationの略)は、インターネット上での認証および許可を管理するための標準プロトコルです。このプロトコルを使うことで、ユーザーは自分のログイン情報(ユーザー名とパスワードなど)を他のウェブサイトやアプリケーションと直接共有することなく、第三者のアプリケーションに自分のデータへの限定的なアクセスを許可することができます。 - リポジトリとブランチを選択し、特定のイベント(例えば、プッシュやプルリクエスト)に基づいてビルドが実行されるようにトリガーを設定します。
- サービスアカウントを選択します。
- 「作成」をクリックします。
cloudbuild.yamlファイルの作成
-
YAMLファイルとは?
YAML(YAML Ain't Markup Language) は、人間が読めるデータシリアライゼーション形式です。主に設定ファイルやデータの書き込み形式として広く使われています。YAMLファイルはデータを階層構造で整理し、可読性を高めるためにインデントを用いています。 - リポジトリのルートディレクトリに cloudbuild.yaml ファイルを作成します。
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/[PROJECT_ID]/[ImageName]', '.']
images:
- 'gcr.io/[PROJECT_ID]/[ImageName]'
serviceAccount: 'projects/[PROJECT_ID]/serviceAccounts/[ServiceAccountsAddress]'
options:
logging: CLOUD_LOGGING_ONLY
[PROJECT_ID]
と[ImageName]
と[ServiceAccountsAddress]
はそれぞれご自身のプロジェクトIDとイメージ名とサービスアカウントアドレスを登録してください。
- トリガーにマッチしたソース変更が発生すると、cloudbuild.yamlに記述された手順に従って自動でビルドが開始されます。
開発環境の最適化
開発環境を最適化することは、プロジェクトの効率と品質を向上させるために重要です。
ここでは上記でビルドしたものをデプロイする方法について紹介いたします。
コンテナイメージの作成
-
Dockerfileは、 あなたのアプリケーションをコンテナイメージとしてパッケージ化するための「レシピ」のようなものです。
これによりアプリケーションの実行環境を一貫して管理することができます。
Dockerfile
# Use the official Node.js image.
# https://hub.docker.com/_/node
FROM node:14
# Create and change to the app directory.
WORKDIR /usr/src/app
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
COPY package*.json ./
# Install production dependencies.
RUN npm install --only=production
# Copy local code to the container image.
COPY . .
# Run the web service on container startup.
CMD [ "node", "app.js" ]
アプリのエントリーポイント
役割: Node.jsアプリケーションのエントリーポイントとなるファイルです。通常、このファイルにはサーバーの設定やルーティングが含まれています。
ファイル内容の例
- Expressなどのフレームワークを使用してHTTPサーバーを設定
- 経路(ルート)の定義
- ミドルウェアの設定
- サーバーの起動
簡単なNode.jsアプリ(例: Webサーバーの立ち上げ)
app.js
const http = require('http');
const hostname = '0.0.0.0';
const port = 8080;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
プロジェクト設定と依存管理ファイル
役割: Node.jsプロジェクトの設定や依存関係を管理するためのファイルです。
ファイル内容の例
- プロジェクト名、バージョン、説明
- 依存しているライブラリやモジュール
- スクリプト(例: npm startで実行するコマンドの定義)
- 開発依存関係(testingやビルドのためのツールなど)
package.json
{
"name": "my-node-app",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"http": "^0.0.1-security"
}
}
Cloud Run を利用したデプロイ
Cloud Run を使ったデプロイは、コンテナ技術を活用して簡単かつスケーラブルなアプリケーションのデプロイを実現します。
- cloudbuild.yaml ファイルに Cloud Run にデプロイできる情報を追加します。
- name: 'gcr.io/cloud-builders/gcloud'
args: ['run', 'deploy', '[CloudRunName]', '--image', 'gcr.io/[PROJECT_ID]/[ImageName]', '--region', 'asia-northeast1', '--platform', 'managed', '--allow-unauthenticated']
[CloudRunName]
はご自身で決めた Cloud Run サービス名を登録してください。
- gcloud を使って Cloud Build を実行します。自動的に Cloud Run にデプロイします。
$ gcloud builds submit --config cloudbuild/cloudbuild.yaml .
- コンソール上で Cloud Run のサービスがデプロイされている事を確認します。Artifact Registry でイメージを確認します。
このような設定を確立することで、gcloud コマンド一つでコードの変更からデプロイまでの一連の流れをスムーズかつ効率的に行うことが可能となります。
まとめ
この記事を通して Git と Google Cloud の基本的な使い方から、それらを連携させた効率的な開発フローの作成方法までの一部を紹介いたしました。
Git はソースコードの管理に欠かせないツールであり、その強力な機能を最大限に活用することで、開発プロジェクトの品質や速度を大幅に改善することができます。
また、Google Cloudと連携することで継続的インテグレーション/デリバリー(CI/CD)のパイプラインをセットアップし、より柔軟でスケーラブルな開発環境を実現できます。
Git について、開発の効率が向上することを願っています。
Discussion