Gitの仕組みとチーム開発の流れを理解する
この記事は「つながる勉強会 Advent Calendar 2022」の8日目の記事です。
背景
チーム開発を始めてからよりgitの仕組みやできること理解する必要性を感じたので、記事にまとめてみました。
Gitとは
Gitとは、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムです。Gitを使用することで1つのプロジェクトをチーム開発していくときに、他メンバーの開発を考慮せずに進めることができます。
Gitリポジトリの作成
Gitリポジトリとは、プロジェクトのリビジョン(修正)と履歴を維持管理するデータベースで、オブジェクト格納領域とインデックスから構成されています。
- オブジェクト格納領域(4つのオブジェクトから構成されています)
- ブロブ
ファイルを圧縮したもの。ブロブにはファイルのデータが含まれていますが、ファイルのメタデータは含まれていません。 - ツリー
ブロブオブジェクトや別のツリーオブジェクトを管理して階層構造を構築します。 - コミット
単一のスナップショットとして、コミットが実行された時点におけるリポジトリの状態を記録しています。 - タグ
特定のオブジェクトに、人が読める情報を加えます。名前を付けるオブジェクトは、通常コミットオブジェクトです。
- ブロブ
- インデックス
一時的かつ動的なバイナリファイルです。ある瞬間のプロジェクト全体の構造を捉えています。
オブジェクト格納領域とインデックスについてはこれらの記事がわかりやすくまとめてありました。
参考記事
ソースコードをGitで管理していくためにはGitリポジトリ必要なので、プロジェクトの開始時にGitリポジトリを作成します。
- 作業ディレクトリの作成
$ mkdir git_practice
- 作業ディレクトリにGitリポジトリを作成
$ cd git_practice
$ git init
- .gitと呼ばれる隠しディレクトリがあるかを確認
git ls -a
でディレクトリ内にあるすべてのフォルダ・ファイルを確認できます。
$ git ls -a
# . .. .git
チーム開発の流れ
チーム開発の流れは基本的に下記の通りです。
- リモートリポジトリをローカルにクローン(最初のみ実行)
- ローカルリポジトリの
develop
ブランチを更新する - 作業ブランチを作成
- 実装
- リモートリポジトリにプッシュ
- リモートリポジトリの
develop
ブランチにマージ - リリース
▼イメージ図
ここからは2・3・5に関して詳細に述べていきます。
リモートリポジトリをローカルにクローン
既存のプロジェクトに参加した場合、git clone
を使用して既存のリポジトリをローカル環境に複製します。新しいクローンでは、デフォルトでリモートリポジトリのアクセス先に対してorigin
と名付けられます。リモートリポジトリのブランチは、クローンにおいてorigin/develop
やorigin/develop
のようにorigin
から始まる名前のブランチ(追跡ブランチ)を利用できます。
リポジトリのクローンの参考記事
ローカルリポジトリのdevelopブランチを更新する
前提として、複数人で開発作業をするときはブランチを使い、他人の開発の影響を受けることなく開発していきます。私の会社ではGit-flowを使用しているので、実装時はdevelop
ブランチから作業ブランチを作成します。
あるイシューを実装するとき、まずローカルリポジトリのdevelop
ブランチとリモートリポジトリのdevelop
ブランチの差分がない状態を作ります。git pull <リモートのリポジトリ名> <リモートのブランチ名>
またはgit fecth <リモートのリポジトリ名>
&git merge <リモートのブランチ名>
でローカルのdevelop
ブランチを更新します。
git pull
の場合
git pull origin develop
git fecth
&git merge
の場合
$ git fetch origin
$ git merge origin/develop
作業ブランチの作成
ブランチはgit branch [ブランチ名]
で作成できます。作成したブランチを作業ディレクトリの作業ブランチに設定します(チェックアウト)。ブランチを作成して、そのままチェックアウトする場合はgit checkout -b
というコマンドを使用します。
- ブランチの作成
$ git branch feature
- チェックアウト
$ git checkout feature
リモートリポジトリにプッシュ
ステージング(git add
)・コミット(git commit
)・プッシュ(git push
)の3ステップを行うことでリモートリポジトリにプッシュができます。実装が完了したら、
インデックスにファイルを登録することをステージングと呼びます。インデックスの役割は、ファイルの変更を記録して、コミットできる段階になるまで安全な状態にしておくことです。gitはファイルを3つに分類しており、git add
されたファイルは追跡ファイルとみなされます。ファイルの状態はgit status
で確認できます。
- 追跡:リポジトリに入っているか、インデックスに登録されているファイル
- 無視:リポジトリから「見えない状態」。.gitignoreファイルで指定することができる
- 未追跡:「未追跡ファイル=作業ディレクトリー追跡ファイル+無視ファイル」
コミットをすると、Gitはインデックスのスナップショットを記録し、そのスナップショットをオブジェクト格納領域に送ります。Gitはインデックスの現在の状態と直近のスナップショットを比較し、変更されたファイルとディレクトリのリストを作成します。変更されたファイルに新たなブロブを作成、変更されたディレクトリに新たなツリーを作成、変更されていないブロブとツリーは再利用します。
コミット後にプッシュをするとリモートリポジトリにコミットが反映されます。
ステージングからプッシュまでのgitの動きをコマンドで確認していきます。
- index.htmlファイル作成
index.htmlはまだインデックスに登録していないので、Untracked filesに分類されている
$ touch index.html
$ git status
#On branch feature
#
#No commits yet
#
#Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# index.html
#
#nothing added to commit but untracked files present (use "git add" to track)m
-
git add
でファイルをステージすると、追跡状態のファイルになる
$ git add index.html
$ git status
#On branch feature
#
#No commits yet
#
#Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: index.html
-
git commit
をするとコミットオブジェクトが作成されます。
$ git commit -m"initial commit"
#[master (root-commit) 3315537] initial commit
#1 file changed, 0 insertions(+), 0 deletions(-)
#create mode 100644 index.html
$ git log
#commit 33155373baed947a86475ea37472f57cd0e88639 (HEAD -> master)
#Author: XXXXX <test@gmail.com>
#Date: Sat Oct 29 15:12:03 2022 +0900
#
# initial commit
-
git push
でリモートリポジトリのfeatureブランチにプッシュします。
$ git push origin feature
この後、プルリクエストをしてレビューでOKがでればdevelopブランチにマージしてイシューは完了です。
参考
Discussion