はじめに
現代のソフトウェア開発において、バージョン管理システムは必要不可欠なツールです。 この章では、GitとGitHubの基本概念を理解し、なぜこれらのツールが世界中の開発者に愛用されているのか、 その理由と仕組みを詳しく学んでいきます。
この章では理論的な内容が中心ですが、次章以降の実践的な学習の基礎となる重要な概念を扱います。じっくりと理解を深めましょう。
1.1 バージョン管理システムとは
バージョン管理が必要な理由
ソフトウェア開発を進めていくと、以下のような課題に直面します:
- 変更履歴の追跡 - いつ、誰が、何を変更したのかを把握したい
- バックアップとリカバリ - 間違った変更を元に戻したい
- チーム開発 - 複数人で同時に開発を進めたい
- 実験的な開発 - 本番に影響を与えずに新機能を試したい
考えてみよう
バージョン管理システムを使わずに、フォルダ名に日付を付けて管理していた経験はありませんか? 「project_20240715」「project_20240716_final」「project_20240716_final_final」のような管理方法の問題点を考えてみましょう。
バージョン管理システムの種類
バージョン管理システムは大きく分けて3つの世代に分類されます:
世代 | 種類 | 代表例 | 特徴 |
---|---|---|---|
第1世代 | ローカルVCS | RCS | 単一ファイルの履歴管理 |
第2世代 | 集中型VCS | SVN, CVS | 中央サーバーで一元管理 |
第3世代 | 分散型VCS | Git, Mercurial | 各開発者が完全なリポジトリを保持 |
1.2 Gitの基本概念
Gitとは何か
Gitは2005年にLinus Torvalds(Linuxの創始者)によって開発された分散型バージョン管理システムです。 以下の特徴により、現在最も広く使われているVCSとなっています:
高速性
ほとんどの操作がローカルで完結するため、非常に高速
分散型
各開発者が完全なリポジトリのコピーを持つ
データ整合性
SHA-1ハッシュによりデータの整合性を保証
ブランチ機能
軽量で高速なブランチ・マージ機能
Gitの3つの状態
Gitでは、ファイルは以下の3つの状態のいずれかに存在します:
1. 作業ディレクトリ (Working Directory)
実際にファイルを編集する場所。あなたが普段コードを書いている場所です。
- 意味:現在作業中のファイルが存在する場所
- 状態:変更済み(Modified)、未追跡(Untracked)
- 操作:ファイルの編集、作成、削除が自由に行える
- 特徴:Gitはここでの変更を自動的に検知しますが、まだ履歴には記録されません
# 作業ディレクトリの状態を確認
git status
# 出力例:
# Changes not staged for commit:
# modified: index.html
# Untracked files:
# newfile.js
2. ステージングエリア (Staging Area / Index)
次のコミットに含める変更を一時的に保存する場所。コミット前の準備場所です。
- 意味:コミットする変更を選別・準備する中間領域
- 状態:ステージング済み(Staged)
- 操作:`git add`で追加、`git reset`で除外
- 特徴:部分的なコミットが可能(一部の変更だけを選んでコミット)
- 利点:論理的にまとまった変更だけをコミットできる
# ファイルをステージングエリアに追加
git add index.html
# 特定の変更だけをステージング
git add -p index.html
# ステージングエリアの内容を確認
git diff --staged
3. リポジトリ (Repository)
コミットされた全ての変更履歴が保存される場所。プロジェクトの完全な歴史です。
- 意味:プロジェクトの全履歴を保持するデータベース
- 状態:コミット済み(Committed)
- 操作:`git commit`で追加、履歴の改変は原則不可
- 特徴:各コミットは一意のSHA-1ハッシュで識別
- 保存内容:ファイルの完全なスナップショット(差分ではない)
# ステージングエリアの内容をリポジトリにコミット
git commit -m "Add new feature"
# コミット履歴を確認
git log --oneline
# 特定のコミットの詳細を確認
git show HEAD
ステージングエリアという中間層を設けることで、以下のような利点があります:
- 選択的コミット:複数の変更から必要なものだけを選んでコミット
- 論理的な単位:関連する変更をまとめて1つのコミットに
- レビューの機会:コミット前に変更内容を確認・調整
- 作業の中断・再開:ステージングした内容を保持したまま他の作業が可能
Gitの基本的な流れを体験
1.3 GitHubとは
GitとGitHubの違い
GitとGitHubはよく混同されますが、全く異なるものです:
Git
- バージョン管理システム(ソフトウェア)
- ローカルで動作
- コマンドラインツール
- 無料・オープンソース
GitHub
- Gitリポジトリのホスティングサービス
- Webベースのプラットフォーム
- コラボレーション機能を提供
- 無料プラン+有料プラン
GitHubの主要機能
GitHubは単なるGitリポジトリのホスティングサービスではなく、開発を効率化する多くの機能を提供しています:
リポジトリ管理
コードの保存、バージョン管理、アクセス制御
プルリクエスト
コードレビューと議論を通じた変更の統合
Issues
バグ報告、機能要望、タスク管理
Projects
カンバンボードによるプロジェクト管理
Actions
CI/CDワークフローの自動化
Wiki & Documentation
プロジェクトのドキュメント管理
1.4 環境構築
Gitのインストール
各OSでのGitのインストール方法を説明します:
Windows
# Git for Windowsをダウンロードしてインストール
# https://git-scm.com/download/win
# または、wingetを使用
winget install --id Git.Git -e --source winget
# または、Chocolateyを使用
choco install git
macOS
# Homebrewを使用
brew install git
# または、Xcodeコマンドラインツールに含まれるGitを使用
xcode-select --install
Linux (Ubuntu/Debian)
# apt-getを使用
sudo apt-get update
sudo apt-get install git
# 最新版をインストールする場合
sudo add-apt-repository ppa:git-core/ppa
sudo apt update
sudo apt install git
Gitの初期設定
Gitをインストールしたら、ユーザー情報を設定します:
# ユーザー名の設定
git config --global user.name "あなたの名前"
# メールアドレスの設定
git config --global user.email "your.email@example.com"
# 設定の確認
git config --list
ここで設定するメールアドレスは、GitHubアカウントで使用するメールアドレスと同じにすることを推奨します。これにより、コミットが正しくGitHubアカウントに関連付けられます。
GitHubアカウントの作成
- github.comにアクセス
- 「Sign up」をクリック
- ユーザー名、メールアドレス、パスワードを入力
- メールアドレスの確認を完了
SSH鍵の設定(推奨)
GitHubとの通信を安全に行うため、SSH鍵を設定することを推奨します:
# SSH鍵の生成
ssh-keygen -t ed25519 -C "your.email@example.com"
# 生成された公開鍵を表示
cat ~/.ssh/id_ed25519.pub
# クリップボードにコピー(macOS)
pbcopy < ~/.ssh/id_ed25519.pub
# クリップボードにコピー(Linux)
xclip -sel clip < ~/.ssh/id_ed25519.pub
生成された公開鍵をGitHubに登録:
- GitHubの Settings → SSH and GPG keys
- 「New SSH key」をクリック
- タイトルを入力し、公開鍵を貼り付け
- 「Add SSH key」で保存
実践演習
以下の手順を実行して、環境構築を完了させましょう:
- Gitをインストールする
- ユーザー名とメールアドレスを設定する
- GitHubアカウントを作成する
- SSH鍵を生成してGitHubに登録する
- 以下のコマンドで接続テストを実行:
ssh -T git@github.com
1.5 Gitの内部構造
Gitオブジェクトモデル
Gitの内部では、全てのデータは「オブジェクト」として管理されています。 主要なオブジェクトタイプは以下の4つです:
Blob (Binary Large Object)
ファイルの内容を保存。ファイル名やメタデータは含まない。
- 役割:ファイルの実際の内容(テキストやバイナリ)を保存
- 特徴:ファイル名や権限情報は持たない(純粋な内容のみ)
- 識別:内容のSHA-1ハッシュ値がオブジェクトID
- 効率性:同じ内容のファイルは1つのBlobオブジェクトを共有
# ファイルのBlobオブジェクトを確認
git hash-object README.md
# 出力例: e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
# Blobの内容を確認
git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
Tree
ディレクトリ構造を表現。Blobや他のTreeへの参照を持つ。
- 役割:ディレクトリ構造とファイル名の対応を管理
- 内容:ファイルモード、オブジェクトタイプ、SHA-1、ファイル名のリスト
- 階層構造:サブディレクトリは別のTreeオブジェクトとして参照
- メタデータ:ファイルの実行権限なども保存
# 現在のTreeオブジェクトを確認
git cat-file -p HEAD^{tree}
# 出力例:
# 100644 blob a1b2c3d... README.md
# 100644 blob e4f5g6h... index.html
# 040000 tree i7j8k9l... src/
Commit
特定時点のプロジェクトのスナップショット。Treeへの参照、親コミット、メタデータを含む。
- 構成要素:
- Treeオブジェクトへの参照(その時点のファイル構造)
- 親コミットへの参照(履歴の連続性)
- 作者情報(名前、メールアドレス、タイムスタンプ)
- コミッター情報(実際にコミットした人)
- コミットメッセージ
- 不変性:一度作成されたコミットは変更不可
- DAG構造:有向非巡回グラフ(Directed Acyclic Graph)を形成
# コミットオブジェクトの詳細を確認
git cat-file -p HEAD
# 出力例:
# tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
# parent a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# author John Doe 1638360000 +0900
# committer John Doe 1638360000 +0900
#
# Add new feature
Tag
特定のコミットに対する固定的な参照。リリースバージョンなどに使用。
- 種類:
- 軽量タグ:単なるコミットへの参照
- 注釈付きタグ:タグオブジェクトとして保存(推奨)
- 用途:リリースバージョン、マイルストーンのマーキング
- 情報:タグ作成者、日時、メッセージ、署名(オプション)
- 不変性:特定のコミットを永続的に参照
# 注釈付きタグの作成
git tag -a v1.0.0 -m "Release version 1.0.0"
# タグオブジェクトの確認
git cat-file -p v1.0.0
# 出力例:
# object a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# type commit
# tag v1.0.0
# tagger John Doe 1638360000 +0900
#
# Release version 1.0.0
Gitのオブジェクトは以下のような階層関係を持ちます:
Tag → Commit → Tree → Blob ↓ Commit(親)→ Tree → Blob ↓ Tree(サブディレクトリ)→ Blob
この構造により、Gitは効率的にファイルの履歴を管理し、 任意の時点のプロジェクト状態を瞬時に復元できます。
SHA-1ハッシュ
Gitでは全てのオブジェクトがSHA-1ハッシュによって識別されます。 これにより、データの整合性が保証され、効率的な重複排除が可能になります。
# オブジェクトのハッシュ値を確認
echo "Hello, Git!" | git hash-object --stdin
# 出力例: d564d0bc3dd917926892c55e3706cc116d5b165e
# 実際のリポジトリでコミットハッシュを確認
git log --oneline
# 出力例:
# a1b2c3d Fix bug in authentication
# e4f5g6h Add user profile feature
# i7j8k9l Initial commit
.gitディレクトリの構造
Gitリポジトリの心臓部である.gitディレクトリの主要な構成要素:
.git/
├── HEAD # 現在のブランチへの参照
├── config # リポジトリ固有の設定
├── description # リポジトリの説明(GitWebで使用)
├── hooks/ # フック・スクリプト
├── index # ステージングエリアの情報
├── info/ # 追加情報(exclude等)
├── logs/ # 参照の更新ログ
├── objects/ # オブジェクトデータベース
└── refs/ # ブランチとタグの参照
├── heads/ # ローカルブランチ
├── remotes/ # リモートブランチ
└── tags/ # タグ
各ディレクトリ・ファイルの詳細説明
HEAD
現在チェックアウトしているブランチへの参照を含むファイル。
# HEADファイルの内容を確認
cat .git/HEAD
# 出力例: ref: refs/heads/main
# 切り離されたHEAD状態の場合
# 出力例: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
config
リポジトリ固有の設定ファイル。ユーザー情報、リモートURL、ブランチ設定など。
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@github.com:username/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
objects/
全てのGitオブジェクト(Blob、Tree、Commit、Tag)が保存されるデータベース。
- 構造:SHA-1ハッシュの最初の2文字でディレクトリを作成し、残りの38文字がファイル名
- 圧縮:zlib形式で圧縮されて保存
- パックファイル:効率化のため、定期的にパックファイルに統合
# objectsディレクトリの構造を確認
find .git/objects -type f | head -5
# 出力例:
# .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
# .git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
# .git/objects/pack/pack-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6.pack
# .git/objects/pack/pack-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6.idx
index
ステージングエリア(インデックス)の情報を保存するバイナリファイル。
- 内容:ステージングされたファイルのパス、権限、タイムスタンプ、SHA-1
- 更新:`git add`コマンドで更新される
- 確認:`git ls-files --stage`で内容を確認可能
# インデックスの内容を確認
git ls-files --stage
# 出力例:
# 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 README.md
# 100644 4b825dc642cb6eb9a060e54bf8d69288fbee4904 0 index.html
refs/
ブランチ、タグ、リモート参照を管理するディレクトリ。
- refs/heads/:ローカルブランチの最新コミットを指す
- refs/remotes/:リモートブランチの追跡情報
- refs/tags/:タグの参照情報
# ブランチの参照を確認
cat .git/refs/heads/main
# 出力例: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# 全ての参照を一覧表示
git show-ref
# 出力例:
# a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0 refs/heads/main
# e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3 refs/remotes/origin/main
# y4z5a6b7c8d9e0f1g2h3i4j5k6l7m8n9o0p1q2r3 refs/tags/v1.0.0
logs/
参照(ブランチ、HEAD)の更新履歴を記録。`git reflog`コマンドで参照。
- 用途:誤操作からの復旧、履歴の追跡
- 保存期間:デフォルトで90日間(設定で変更可能)
- 内容:各操作の前後のSHA-1、操作内容、タイムスタンプ
.gitディレクトリは、プロジェクトの全履歴と設定を含む重要なディレクトリです。 このディレクトリを削除すると、Gitリポジトリではなくなり、全ての履歴が失われます。 一方、作業ディレクトリのファイルを全て削除しても、.gitディレクトリがあれば 最新の状態を復元できます。
1.6 まとめと次のステップ
この章で学んだこと
- バージョン管理システムの必要性と種類
- Gitの基本概念と3つの状態
- GitとGitHubの違いと関係性
- 開発環境のセットアップ
- Gitの内部構造の基礎
理解度チェック
確認問題
- 分散型バージョン管理システムの利点を3つ挙げてください
- Gitの3つの状態とそれぞれの役割を説明してください
- GitHubが提供する主要な機能を5つ挙げてください
- SHA-1ハッシュがGitでどのように使われているか説明してください
次章への準備
第2章では、実際にGitを使って基本的な操作を行います。 以下の準備が完了していることを確認してください:
- Gitがインストールされている
- ユーザー名とメールアドレスが設定されている
- GitHubアカウントが作成されている
- SSH接続が設定されている(推奨)
次章では実際に手を動かして学習します。 ターミナル(コマンドプロンプト)の基本的な操作に慣れていない場合は、 基本的なコマンド(cd, ls/dir, mkdir等)を予習しておくとスムーズに進められます。