お願い
本記事の内容に誤りや改善点がございましたら、コメント等でご指摘いただけますと幸いです。
なお、本記事は個人の学習記録として作成したものです。業務でご利用の際は、公式ドキュメントもあわせてご確認ください。
1. はじめに
普段会社でもGit (GitHub)を使用していますが、基本的なコマンド操作の裏側でどのような動きをしているか意識できていなかったので、まとめてみたいと思います。
初心者向けの知識だと思いますので、Gitをこれから利用する人、利用したばかりの人に向けて書きます!
2. Git、GitHubとは
Gitは分散型のバージョン管理システムです。
集中型のバージョン管理システム(Subversion等)とは異なり、複数のリポジトリが存在するため、管理が比較的複雑になります。
しかし、データが分散していることでデータが消えにくかったり、リモートリポジトリに接続できない環境でも開発が行えるというメリットがあります。
最初に混同しがちなのがGitとGitHubです。これらは別物です。
Gitはバージョン管理システムの種類です。
それに対して、GitHubはGitのリポジトリ(ソースコードなどのデータ)を管理するWebサービスです。
このようなサービスをホスティングサービスと呼びます。
ほかにも代表的なホスティングサービスにBitbucket、GitLab、Backlogなどがあります。
今回はGitHubで説明を行いますが、GitHubで問題なくGit操作が行えれば、ほかのサービスでも問題なくGitを扱えると思います。
3. GitHubの始め方
GitHubの始め方、実際のコマンド操作の例は下記の記事をご確認ください。
Gitコマンドの内部動作と基本用語まとめ(後編)(実際に操作してみる)
4. 超頻出の基本的な用語
Gitを使うなら、これだけは知っておきたい用語を説明します。
リポジトリ(repository)
プロジェクトのファイルとか、変更の履歴を保存する場所のこと。
リポジトリは2種類あります。
- リモートリポジトリ: サーバー(GitHubとか)にある、みんなで共有するリポジトリ
- ローカルリポジトリ: 自分のPCにある、作業用のリポジトリ
クローン(clone)
リモートリポジトリのコピーをローカル(自分のPC)に作成します。
これでできたコピーがローカルリポジトリです。
プル(oull)
リモートの最新変更をローカルに取り込みます。
コミット(commit)
ファイルの変更を記録すること。
「いつ、誰が、何を変えたか」っていう情報が保存されます。
プッシュ(push)
ローカルの新しいコミットをリモートに転送します。
共有先で他の人が取得できるようにアップロードします。
ブランチ(branch)
開発の流れを分ける機能です。メインの流れを壊さずに、新しい機能を作ったり、バグを直したりできます。
普通はmain(またはmaster)っていう名前のブランチが最初に作られます。
※詳しくは「8. ブランチ操作」に記載。
5. Gitの3つのエリア
Gitでは、ファイルの変更は3つの段階を通って管理されます。
Working Directory(作業中のファイル)
↓ git add
Staging Area(コミットされるのを待っているファイル)
↓ git commit
Local Repository(変更履歴が記録された場所)
↓ git push
Remote Repository(みんなで共有する場所、バックアップ)
逆に、リモートにある変更をローカルへ持ってくる場合は、
Remote Repository
│ git fetch(履歴データだけを Local Repository へ取得)
↓ ※ここでは 自分の作業中のファイル(Working Directory)が書き換わらない
Local Repository
│ git merge(Local の内容を Staging Area と Working Directory へ反映)
│ ※ここで 自分の作業中のファイル(Working Directory)が書き換わる
↓
Staging Area
Working Directory
※この流れを一気におこなうのが git pull
1. Working Directory(ワーキングディレクトリ)
ファイルを編集する場所です。
コードを書いたり、ファイルを追加したり、削除したりすると、この場所で変更が起こります。
この時点では、Gitはまだ変更を知りません。
2. Staging Area(ステージングエリア)
次のコミットに入れる変更を、一時的に置いておく場所です。
git addコマンドを使うと、変更がステージングエリアに登録されます。
なぜこの段階があるのかと言うと、作業中のファイルがいっぱいあっても、「このファイルだけコミットしたい」みたいなことができるかららしいです。
ただ、GUI操作しているとコミットしたものを一覧で見て、追加削除できるので意識しないところだと思います。
3. Local Repository(ローカルリポジトリ)
コミットされた変更が、永続的に保存される場所です。
.gitというフォルダの中に、データベースとして保存されています。
git commitをすると、ステージングエリアの内容がローカルリポジトリに記録されて、変更の履歴が残ります。
4. Remote Repository(リモートリポジトリ)
GitHubとかにある、みんなで共有するリポジトリです。
git pushでローカルの変更をアップロードして、git pullでリモートの変更をダウンロードします。
6. 超頻出の基本的なコマンド
コマンド自体は覚える必要はなく、個人的には動きさえ分かっていればいいと思っています。
内部の動きを理解するためにあえてこの記事ではコマンドを使用しますが、
実際の現場では、無理にコマンドは使用せず、GitHub DesktopやTortoiseGit、SourceTreeなどGUI操作ができるものも多数あるので活用していきましょう!
6-1. clone - リポジトリのコピー
git clone <URL>
何をする?
リモートリポジトリのコピーをローカル(自分のPC)に作成します。
これでできたコピーがローカルリポジトリです。
内部の動き
- リモートリポジトリの情報(コミット履歴・ブランチ情報など)をローカルにコピー
-
.gitディレクトリ(リポジトリ本体)とワークディレクトリの両方が作成される - 初期状態で
HEAD(ブランチの向き先)が主要ブランチ(mainなど)を指す - 作業ディレクトリにはそのブランチの最新コミット内容が展開されます
6-2. add - ステージングへの追加
git add <file>
# または全ての変更をステージング
git add .
何をする?
Working Directory の変更を Staging Area へ登録します。
これによりコミット対象としてGitが認識するようになります。
内部の動き
- 変更したファイルの
blobオブジェクト(ファイルの情報)を.git/objectsに記録
6-3. commit - 変更の記録
git commit -m "コミットメッセージ"
何をする?
ステージングエリアにある変更を永続的な履歴として記録します。
ローカルリポジトリにコミットオブジェクトを生成します。
内部の動き
- インデックス(ステージングエリア)の内容をもとに、'treeオブジェクト'(ディレクトリの情報)を
.git/objectsに記録 -
commitオブジェクト(メタデータ、ツリー、親コミットへの参照)を.git/objectsに記録 - 現在のブランチ(main など)の先端が新しいコミットに移動し、それに伴い
HEAD(ポインタ)も最新のコミットを指すようになる。
補足
コミットメッセージには、下記の2点を書いておくとわかりやすくなると思います。
- 何を変更したかを簡潔に書く(例: ログイン機能を追加)
- 「なぜ」その変更が必要だったかも書くとより良い
6-4. push - リモートへのアップロード
git push
# 初回は以下のように指定が必要な場合があります
git push -u origin main
何をする?
ローカルの新しいコミットをリモートに転送します。
共有先で他の人が取得できるようにアップロードします。
内部の動き
- オブジェクト(blob・tree・commit・tag)をリモートに送信
- リモートの参照(例:
origin/main)を更新(ポインタ移動)
注意点
- リモートに他の人の変更がある場合、先に
pullする必要があります
6-5. pull - リモートからの取得
git pull
何をする?
リモートの最新変更をローカルに取り込みます。
実際には fetch + merge(または rebase)が行われます。
内部の動き
- リモートの新しいコミットを取得(
git fetch) - 取得した変更を現在のブランチに統合(マージまたはリベース)
注意点
コンフリクト(他の人も同じ場所に変更を加えていること)がある場合は手動で解決が必要になります。
定期的に pull することで、大きなコンフリクトを避けられます。
6-6. checkout - ブランチの切り替え
git checkout <branch-name>
# 新しいブランチを作成して切り替え
git checkout -b <new-branch-name>
何をする?
作業するブランチを切り替えます。
Working Directory の内容が指定したブランチの状態に更新されます。
内部の動き
-
HEADが指定したブランチを指すように更新 -
Working Directoryとindexが、そのブランチの最新コミットの内容に更新される
注意点
未コミットの変更がある状態で checkout すると、コンフリクトがある場合はエラーになります。
先にコミットするか stash(一時的に作業内容を別の場所に保存する)をすると安全に切り替えられます。
7. 状態を確認するコマンド
Gitの現在の状態を確認するためのコマンドです。
コンフリクトが起きた際など問題が起きた際の調査に使います。
7-1. status - 現在の状態確認
git status
Working Directory、Staging Area、Local Repository の差分を確認できます。
- どのファイルが変更されているか
- どのファイルがステージングされているか
- どのファイルが未追跡(Untracked)か
7-2. diff - 差分の確認
# Working Directory と Staging Area の差分
git diff
# Staging Area と最新コミットの差分
git diff --cached
# 特定のコミット間の差分
git diff <commit1> <commit2>
7-3. log - コミット履歴の確認
# 基本的なログ表示
git log
# 簡潔な1行表示
git log --oneline
# グラフ表示
git log --graph --oneline --all
8. ブランチ操作
機能ごとや担当者ごとにブランチを作成して、複数の作業を並行して進められます。
8-1. branch - ブランチの作成と確認
# 現在のブランチ一覧を表示
git branch
# 新しいブランチを作成
git branch <branch-name>
# 既にあるブランチに切り替える
git checkout <new-branch-name>
# 新しいブランチを作成して、切り替え
git checkout -b <new-branch-name>
# ブランチを削除
git branch -d <branch-name>
8-2. merge - ブランチの統合
指定したブランチの変更を現在のブランチに統合します。
# Fast-forward merge(デフォルト)
git merge <branch-name>
# 非Fast-forward merge
git merge --no-ff <branch-name>
# 再帰的merge(分岐がある状況でgit merge <branch-name>を実行すれば自動で再帰的mergeになる)
git merge --no-ff <branch-name>
# Squash merge
git merge --squash <branch-name>
git commit -m "commit message" # squashはコミットが自動作成されないので別途必要
mergeの種類
-
Fast-forward merge:
派生元のブランチに新しいコミットがない場合、mergeコミットを作らずポインタを前に進めるだけ
-
非Fast-forward merge(--no-ff):
Fast-forwardできる状況でも、意図的にマージコミットを作成する。
「このブランチをmergeした」という履歴を残したい場合に使う。
(GitHubのGUIだとCreate a merge commitにあたる)
-
再帰的 merge:
両方のブランチに新しいコミットがある場合に自動で行われる。
分岐前の共通コミットを基準に両方の変更を統合し、新しいマージコミットを作成する。
-
Squash merge(--squash):
ブランチの複数のコミットを1つにまとめてマージする。
履歴をシンプルに保ちたい場合に使う。
(GitHubのGUIだとSquash and mergeにあたる)
9. よくあるトラブルと対処法
9-1. コンフリクト(競合)が発生した
同じファイルの同じ箇所を複数人が編集すると、コンフリクトが発生します。
対処法
-
git statusでコンフリクトしているファイルを確認 - ファイルを開き、
<<<<<<<、=======、>>>>>>>で囲まれた部分を編集 - どちらの変更を採用するか、または両方を統合するかを決定
-
git add <file>でコンフリクト解決を記録 -
git commitでマージを完了
9-2. 間違えてコミットしてしまった
直前のコミットを修正したい場合
# ファイルを修正して
git add <file>
git commit --amend
コミットを取り消したい場合
# コミットは取り消すが、変更は残す
git reset --soft HEAD^
# コミットも変更も取り消す
git reset --hard HEAD^
9-3. 作業途中で別のブランチに移りたい
# 現在の変更を一時保存
git stash
# 別の作業を行う...
# 保存した変更を復元
git stash pop
10. GitHubの便利な機能
10-1. Fork(フォーク)
他人のリポジトリを自分のアカウントにコピーする機能です。
書き込み権限を持っていないプロジェクト(オープンソースプロジェクトなど)の開発を行うときは、この機能を使用します。
- GitHubで対象のリポジトリページを開く
- 右上の「Fork」ボタンをクリック
- 自分のアカウントにコピーが作成される
10-2. Pull Request(プルリクエスト)
自分の変更をプロジェクトのメインブランチに統合してもらうためのリクエストです。
- ブランチで作業してpush
- GitHubで「Pull Request」を作成
- レビュー担当者が内容を確認
- 承認されたらメインブランチにマージ
10-3. Issues(課題管理)
バグ報告や機能要望を管理する機能です。
11. 開発フロー
11-1. Git Flow
複雑なプロジェクトに適した開発フロー。
大規模な開発で使用されます。
-
main: 本番環境用 -
develop: 開発用のメインブランチ -
feature/*: 新機能開発用 -
release/*: リリース準備用 -
hotfix/*: 緊急修正用
11-2. GitHub Flow
シンプルで理解しやすいフロー。
小規模チームや頻繁にデプロイをする場合に向いています。
-
mainブランチは常にデプロイ可能な状態 - 新機能や修正はブランチを作成して作業
- Pull Requestでレビュー
- 承認されたら
mainにマージ - マージ後すぐにデプロイ
12. まとめ
- Gitの仕組み: 4つのエリア(Work/Stage/Local/Remote)をデータが移動する流れを理解。
-
基本操作:
addで選別、commitで記録、pushで共有、pullで同期。 -
ブランチ:
mainを汚さず、枝分かれさせて安全に並行作業を行う。 -
マージ: 履歴をどう残すかに合わせて、通常マージや
squashなどを使い分ける。 -
GitHub:
Pull Requestを活用し、レビューを経て安全にチーム開発を進める。
補足
もっとGit(GitHub)の詳しい話を知りたい方は、下記のサイト、本がおすすめです。