はじめに

現代のソフトウェア開発において、バージョン管理システムは必要不可欠なツールです。 この章では、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はここでの変更を自動的に検知しますが、まだ履歴には記録されません
Bash
# 作業ディレクトリの状態を確認
git status
# 出力例:
# Changes not staged for commit:
#   modified:   index.html
# Untracked files:
#   newfile.js

2. ステージングエリア (Staging Area / Index)

次のコミットに含める変更を一時的に保存する場所。コミット前の準備場所です。

  • 意味:コミットする変更を選別・準備する中間領域
  • 状態:ステージング済み(Staged)
  • 操作:`git add`で追加、`git reset`で除外
  • 特徴:部分的なコミットが可能(一部の変更だけを選んでコミット)
  • 利点:論理的にまとまった変更だけをコミットできる
Bash
# ファイルをステージングエリアに追加
git add index.html
# 特定の変更だけをステージング
git add -p index.html
# ステージングエリアの内容を確認
git diff --staged

3. リポジトリ (Repository)

コミットされた全ての変更履歴が保存される場所。プロジェクトの完全な歴史です。

  • 意味:プロジェクトの全履歴を保持するデータベース
  • 状態:コミット済み(Committed)
  • 操作:`git commit`で追加、履歴の改変は原則不可
  • 特徴:各コミットは一意のSHA-1ハッシュで識別
  • 保存内容:ファイルの完全なスナップショット(差分ではない)
Bash
# ステージングエリアの内容をリポジトリにコミット
git commit -m "Add new feature"
# コミット履歴を確認
git log --oneline
# 特定のコミットの詳細を確認
git show HEAD
なぜ3つの状態が必要なのか?

ステージングエリアという中間層を設けることで、以下のような利点があります:

  • 選択的コミット:複数の変更から必要なものだけを選んでコミット
  • 論理的な単位:関連する変更をまとめて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

PowerShell
# Git for Windowsをダウンロードしてインストール
# https://git-scm.com/download/win

# または、wingetを使用
winget install --id Git.Git -e --source winget

# または、Chocolateyを使用
choco install git

macOS

Bash
# Homebrewを使用
brew install git

# または、Xcodeコマンドラインツールに含まれるGitを使用
xcode-select --install

Linux (Ubuntu/Debian)

Bash
# 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をインストールしたら、ユーザー情報を設定します:

Bash
# ユーザー名の設定
git config --global user.name "あなたの名前"

# メールアドレスの設定
git config --global user.email "your.email@example.com"

# 設定の確認
git config --list
重要

ここで設定するメールアドレスは、GitHubアカウントで使用するメールアドレスと同じにすることを推奨します。これにより、コミットが正しくGitHubアカウントに関連付けられます。

GitHubアカウントの作成

  1. github.comにアクセス
  2. 「Sign up」をクリック
  3. ユーザー名、メールアドレス、パスワードを入力
  4. メールアドレスの確認を完了

SSH鍵の設定(推奨)

GitHubとの通信を安全に行うため、SSH鍵を設定することを推奨します:

Bash
# 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に登録:

  1. GitHubの Settings → SSH and GPG keys
  2. 「New SSH key」をクリック
  3. タイトルを入力し、公開鍵を貼り付け
  4. 「Add SSH key」で保存

実践演習

以下の手順を実行して、環境構築を完了させましょう:

  1. Gitをインストールする
  2. ユーザー名とメールアドレスを設定する
  3. GitHubアカウントを作成する
  4. SSH鍵を生成してGitHubに登録する
  5. 以下のコマンドで接続テストを実行:
    ssh -T git@github.com

1.5 Gitの内部構造

Gitオブジェクトモデル

Gitの内部では、全てのデータは「オブジェクト」として管理されています。 主要なオブジェクトタイプは以下の4つです:

Blob (Binary Large Object)

ファイルの内容を保存。ファイル名やメタデータは含まない。

  • 役割:ファイルの実際の内容(テキストやバイナリ)を保存
  • 特徴:ファイル名や権限情報は持たない(純粋な内容のみ)
  • 識別:内容のSHA-1ハッシュ値がオブジェクトID
  • 効率性:同じ内容のファイルは1つのBlobオブジェクトを共有
Bash
# ファイルのBlobオブジェクトを確認
git hash-object README.md
# 出力例: e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

# Blobの内容を確認
git cat-file -p e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

Tree

ディレクトリ構造を表現。Blobや他のTreeへの参照を持つ。

  • 役割:ディレクトリ構造とファイル名の対応を管理
  • 内容:ファイルモード、オブジェクトタイプ、SHA-1、ファイル名のリスト
  • 階層構造:サブディレクトリは別のTreeオブジェクトとして参照
  • メタデータ:ファイルの実行権限なども保存
Bash
# 現在の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)を形成
Bash
# コミットオブジェクトの詳細を確認
git cat-file -p HEAD
# 出力例:
# tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
# parent a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
# author John Doe  1638360000 +0900
# committer John Doe  1638360000 +0900
#
# Add new feature

Tag

特定のコミットに対する固定的な参照。リリースバージョンなどに使用。

  • 種類
    • 軽量タグ:単なるコミットへの参照
    • 注釈付きタグ:タグオブジェクトとして保存(推奨)
  • 用途:リリースバージョン、マイルストーンのマーキング
  • 情報:タグ作成者、日時、メッセージ、署名(オプション)
  • 不変性:特定のコミットを永続的に参照
Bash
# 注釈付きタグの作成
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ハッシュによって識別されます。 これにより、データの整合性が保証され、効率的な重複排除が可能になります。

Bash
# オブジェクトのハッシュ値を確認
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ディレクトリの主要な構成要素:

Directory Structure
.git/
├── HEAD           # 現在のブランチへの参照
├── config         # リポジトリ固有の設定
├── description    # リポジトリの説明(GitWebで使用)
├── hooks/         # フック・スクリプト
├── index          # ステージングエリアの情報
├── info/          # 追加情報(exclude等)
├── logs/          # 参照の更新ログ
├── objects/       # オブジェクトデータベース
└── refs/          # ブランチとタグの参照
    ├── heads/     # ローカルブランチ
    ├── remotes/   # リモートブランチ
    └── tags/      # タグ

各ディレクトリ・ファイルの詳細説明

HEAD

現在チェックアウトしているブランチへの参照を含むファイル。

Bash
# HEADファイルの内容を確認
cat .git/HEAD
# 出力例: ref: refs/heads/main

# 切り離されたHEAD状態の場合
# 出力例: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
config

リポジトリ固有の設定ファイル。ユーザー情報、リモートURL、ブランチ設定など。

INI
[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形式で圧縮されて保存
  • パックファイル:効率化のため、定期的にパックファイルに統合
Bash
# 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`で内容を確認可能
Bash
# インデックスの内容を確認
git ls-files --stage
# 出力例:
# 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0    README.md
# 100644 4b825dc642cb6eb9a060e54bf8d69288fbee4904 0    index.html
refs/

ブランチ、タグ、リモート参照を管理するディレクトリ。

  • refs/heads/:ローカルブランチの最新コミットを指す
  • refs/remotes/:リモートブランチの追跡情報
  • refs/tags/:タグの参照情報
Bash
# ブランチの参照を確認
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リポジトリではなくなり、全ての履歴が失われます。 一方、作業ディレクトリのファイルを全て削除しても、.gitディレクトリがあれば 最新の状態を復元できます。

1.6 まとめと次のステップ

この章で学んだこと

  • バージョン管理システムの必要性と種類
  • Gitの基本概念と3つの状態
  • GitとGitHubの違いと関係性
  • 開発環境のセットアップ
  • Gitの内部構造の基礎

理解度チェック

確認問題

  1. 分散型バージョン管理システムの利点を3つ挙げてください
  2. Gitの3つの状態とそれぞれの役割を説明してください
  3. GitHubが提供する主要な機能を5つ挙げてください
  4. SHA-1ハッシュがGitでどのように使われているか説明してください

次章への準備

第2章では、実際にGitを使って基本的な操作を行います。 以下の準備が完了していることを確認してください:

  • Gitがインストールされている
  • ユーザー名とメールアドレスが設定されている
  • GitHubアカウントが作成されている
  • SSH接続が設定されている(推奨)
学習のヒント

次章では実際に手を動かして学習します。 ターミナル(コマンドプロンプト)の基本的な操作に慣れていない場合は、 基本的なコマンド(cd, ls/dir, mkdir等)を予習しておくとスムーズに進められます。