Git 教科書
はじめに

この教科書について

このWebアプリは、Gitを「まったく触ったことがない人」から「なんとなく使っている人」までを対象に、概念 → 手を動かす → 実戦の順で学べる教科書です。全部で19章あり、各章の末尾には「読了ボタン」、最終章には確認テストが用意されています。

この教科書の使い方

  • 順番に読むのがおすすめです。前の章の内容が次の章の土台になっています。
  • コードブロック右上の「コピー」ボタンでコマンドをコピーし、自分のターミナルで実際に打ってみてください。手を動かさないと身になりません
  • 読み進めた章の「読了」ボタンを押すと、左の目次に ✓ が付き、進捗が保存されます(ブラウザに記録されます)。
  • 困ったときは左上の検索ボックスか、最後の「コマンドチートシート」「トラブルシューティングFAQ」へどうぞ。
  • キーボードの でも章を移動できます。
対象環境 コマンドはWindows(PowerShell または Git Bash)とmacOS(ターミナル)の両方で共通のものを使います。画面ショットが異なる場合でも、打ち込むコマンドは同じです。
学習のゴール この教科書を読み終える頃には、「自分のPCでリポジトリを作り、コミットを積み、GitHubにpushし、仲間とブランチで並行開発し、コンフリクトを自力で解決できる」ようになっているはずです。
第1章

Gitとは? — バージョン管理の基本概念

こんな経験はありませんか?

レポートやソースコードを書いていて、こんなファイル名を使ったことはありませんか?

あるある
report_最終版.docx
report_最終版2.docx
report_最終版_提出用_修正済み.docx
report_最終版_提出用_修正済み_本当に最終.docx   # ← もうどれが正しいのか分からない

「前の状態に戻したい」「どこを変更したのか分からない」「仲間と同じファイルを編集して上書きし合った」——こうした問題をすべて解決するのがバージョン管理システムで、そのデファクトスタンダードが Git(ギット)です。2005年にLinuxの生みの親リーナス・トーバルズによって開発されました。

Gitでできること

  • いつでも過去に戻れる:すべての変更履歴が保存されるので、好きな時点の状態を復元できます。
  • 変更箇所が一目で分かる:誰が・いつ・どこを・なぜ変えたかが記録されます。
  • 安全に並行開発できる:「ブランチ」機能で、本体を壊さずに実験的な変更ができます。
  • 仲間と協力できる:GitHubなどのサービスを介して、複数人で同じプロジェクトを開発できます。

Gitは「スナップショット」を記録する

Gitはファイル全体の「差分」ではなく、コミットごとのスナップショット(その時点の全ファイルの状態)を記録します。変更されていないファイルは前のスナップショットへの参照が使われるため効率的です。この仕組みのおかげで「いつでもその時点の状態を丸ごと復元する」ことが高速にできるのです。

3つの「場所」を理解しよう — 最重要概念

Gitを使いこなす鍵は、ファイルが移動する3つの領域を理解することです。

作業ディレクトリ
Working Directory
いま実際に編集しているファイルの場所
git add
(ステージング)
ステージングエリア
Index / Stage
「次のコミットに入れる変更」を仮置きする場所
git commit
(確定・記録)
リポジトリ
.git フォルダ
歴代のスナップショット(履歴)が保存される場所

なぜ「保存するだけ」でなく、間にステージングがあるのでしょうか? それは「コミットに含める変更を自分で選別する」ためです。10個のファイルを編集しても、関連する3つだけを選んで1つのコミットにまとめる、ということができます。

ローカルリポジトリ
自分のPCの中の履歴
git push
(アップロード)
リモートリポジトリ
GitHubなど、みんなで共有する履歴
git pull
(ダウンロード)

「分散型」バージョン管理とは

Gitは分散型です。各メンバーがリポジトリ(履歴ごと全部)を手元に持ちます。そのため:

  • ネットに繋がっていなくても、履歴閲覧・コミット・ブランチ操作がすべてできる
  • サーバー(GitHub)が障害を起こしても、誰かの手元に完全な履歴がある
  • push/pull は「履歴のやり取り」なので、自由なタイミングで同期できる
Git と GitHub は別物 Gitは「バージョン管理ソフト(みんなのPCに入れる道具)」、GitHubは「Gitリポジトリを置いて共有・協力するためのWebサービス」です。GitHubの代わりにGitLabやBitbucketを使うチームもあります(GitLabについては第15章で詳しく扱います)。

まず覚えるべき用語

用語意味
リポジトリ履歴を管理しているプロジェクトの保管庫(.git フォルダを含むディレクトリ)
コミット変更を履歴に記録する操作、またはその記録された状態。いつでも戻れる「セーブポイント」
ブランチ履歴の流れを分岐させる機能。作業を互いに干渉せず並行して進められる
HEAD「いま自分がどのコミット・ブランチにいるか」を指すポインタ
ワークツリー実際にエディタで開いて編集しているファイル群(作業ディレクトリとほぼ同義)
リモートネット上にある共有リポジトリ(GitHubなど)。慣例的に origin という名前で登録する
第2章

環境構築と初期設定

2-1. Gitをインストールする

Windows:公式サイト git-scm.com からインストーラをダウンロードして実行します。基本はデフォルト設定のままでOKです(Git Bash というターミナルも一緒に入ります)。あるいは管理者権限のPowerShellで winget install --id Git.Git -e でも入ります。

macOS:ターミナルで git --version を実行すると、まだ入っていなければコマンドライン・デベロッパ・ツールのインストールを促されるので指示に従います。Homebrewを使うなら brew install git が確実です。

動作確認

ターミナル
$ git --version
git version 2.46.0    # ← バージョンが表示されれば成功

2-2. 初期設定(名前とメールアドレス)

Gitのコミットには「誰が作ったか」が記録されます。まず自分の名前とメールアドレスを登録しましょう。--global を付けると、そのPCの全リポジトリで共通の設定になります。

ターミナル
# 名前を登録(本名やGitHubの表示名。日本語もOK)
$ git config --global user.name "Taro Yamada"

# メールアドレスを登録(GitHubに登録するものと同じにするのがおすすめ)
$ git config --global user.email "taro@example.com"

# 登録内容の確認
$ git config user.name
Taro Yamada
なぜメールアドレスが大事? GitHubは「コミットに記録されたメールアドレス」であなたのアカウントと紐づけます。一致していないと、GitHub上で緑色の草(コントリビューショングラフ)が生えません。

あわせて入れておくと便利な設定:

ターミナル
# 新しいリポジトリの既定ブランチ名を main にする(現代の標準)
$ git config --global init.defaultBranch main

# コミットメッセージ編集用のエディタ(VS Code の場合の例)
$ git config --global core.editor "code --wait"

# Windowsのみ:改行コードの自動変換(Windowsは true / Mac は input が定番)
$ git config --global core.autocrlf true    # Windows
$ git config --global core.autocrlf input   # macOS

# 設定一覧を確認
$ git config --list

2-3. GitHubアカウントとSSH接続(後で使う準備)

第5章以降でGitHubを使います。この機会にアカウント作成と、パスワード代わりになるSSH鍵の登録を済ませておきましょう。

  1. github.com でアカウントを作る。
  2. PCでSSH鍵ペア(秘密鍵・公開鍵)を生成する:
ターミナル
# 鍵ペアを生成(メールは自分のもの。パスフレーズは空でも可)
$ ssh-keygen -t ed25519 -C "taro@example.com"

# 公開鍵の中身を表示してコピーする
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1... taro@example.com
  1. GitHub → Settings → SSH and GPG keysNew SSH key にコピーした公開鍵を貼り付けて保存。
  2. 接続テスト:
ターミナル
$ ssh -T git@github.com
Hi taro-yamada! You've successfully authenticated...   # ← これが出れば成功
秘密鍵は絶対に公開しない id_ed25519(拡張子なし・.pubが付いていない方)が秘密鍵です。GitHubに登録するのは必ず公開鍵(.pub)の方。秘密鍵を誰かに送ったり、SNSやブログに載せたりしてはいけません。
第3章

基本のワークフロー — リポジトリ作成からコミットまで

いよいよ手を動かします。この章の流れはすべてのGit利用の基本になるので、必ず自分のPCで試してください。

3-1. リポジトリを作る(git init)

まず、管理したいプロジェクトのフォルダをGitリポジトリとして初期化します。

ターミナル
# 練習用フォルダを作って移動
$ mkdir my-project
$ cd my-project

# このフォルダをGitリポジトリとして初期化
$ git init
Initialized empty Git repository in .../my-project/.git/

git init を実行すると、フォルダの中に .git フォルダ(隠しフォルダ)が作られます。ここに履歴のすべてが保存されます。このフォルダを消すと履歴が消えるので、削除・編集しないでください。

3-2. 状態を確認する(git status)

git status最もよく使うコマンドです。「いま何が変わっていて、何がステージされていて、コミットできる状態か」がすべて分かります。迷ったらまず git status

ターミナル
$ git status
On branch main

No commits yet

nothing to commit (create/copy files and use "git add")

試しにファイルを作ってから再度見てみます。

ターミナル
# ファイルを1つ作る
$ echo "こんにちはGit" > hello.txt

$ git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.txt

nothing added to commit but untracked files present

hello.txtUntracked files(未追跡) として表示されました。Gitは新しいファイルを「まだ管理していないよ」と教えてくれています。親切なことに、次に打つべきコマンド(git add)までヒントとして表示してくれています。

3-3. ステージングする(git add)

ターミナル
# hello.txt をステージング
$ git add hello.txt

# 変更されたファイルを全部ステージング(よく使う形)
$ git add .

$ git status
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   hello.txt

git status の見方のまとめ:

表示意味対処
Untracked filesGitがまだ管理していない新規ファイルgit add で管理開始
Changes not staged管理中のファイルに変更がある(未ステージ)git add でステージング
Changes to be committedステージ済み。コミット待ちgit commit で記録
nothing to commit変更なし。作業ディレクトリはきれい

3-4. 履歴に記録する(git commit)

ターミナル
# -m でコミットメッセージを指定してコミット
$ git commit -m "最初のコミット:hello.txt を追加"
[main (root-commit) a1b2c3d] 最初のコミット:hello.txt を追加
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

コミットメッセージは未来の自分と仲間のための大切な記録です。「何を・なぜ」変更したのかが分かる文章を心がけましょう。

良いメッセージの例 ログイン機能にバリデーションを追加(メール形式チェック)
良くない例: 修正wipああああ —— 後から履歴を見ても何も分かりません。
コミットの単位 「1つの目的につき1コミット」が基本です。「ログイン機能の追加」と「READMEの修正」は別々のコミットに。後で部分的に戻したり調べたりしやすくなります。

3-5. 日常の基本サイクル

以上をまとめると、Gitでの普段の作業はこの繰り返しです。

① 編集する
エディタでファイルを書き換える
② 確認する
git status / git diff
③ ステージする
git add .
④ 記録する
git commit -m "…"

コミットは小まめに。ゲームのセーブと同じで、细かくセーブしておくほど好きな場所に戻りやすいのです。

第4章

履歴を見る・比べる — log と diff

4-1. 履歴を見る(git log)

ターミナル
$ git log
commit a1b2c3d4e5f6... (HEAD -> main)
Author: Taro Yamada <taro@example.com>
Date:   Fri Sep 5 10:00:00 2026 +0900

    最初のコミット:hello.txt を追加

各行の commit の後の英数字(a1b2c3d…)はコミットハッシュ — コミットの世界唯一のIDです。先頭7桁だけ覚えれば十分で、他のコマンドでコミットを指定するときに使います。(HEAD -> main) は「いま main ブランチの先端にいる」という意味です。

覚えておくと便利なオプション:

ターミナル
# 1コミット1行でコンパクトに表示(実務で最常用)
$ git log --oneline

# グラフ付き(ブランチの分岐・合流が見える)
$ git log --oneline --graph --all

# 特定ファイルの変更履歴だけ
$ git log --oneline hello.txt

# 直近3件だけ
$ git log -3

# 変更内容も一緒に表示(q で終了)
$ git log -p
ログの閲覧中に log はページャー(less)で開くので、q で終了、j/k(または矢印キー)でスクロールできます。

4-2. 変更差分を見る(git diff)

ターミナル
# 作業ディレクトリ(未ステージ)の変更を見る
$ git diff

# ステージ済みの変更を見る
$ git diff --staged

# 特定ファイルだけ
$ git diff hello.txt

出力の読み方:

diffの出力例
@@ -1 +1,2 @@
 こんにちはGit
+Gitをはじめました        # + が追加された行
-こんにちはWorld          # - が削除された行
よくある混乱 git diff は「作業ディレクトリ vs ステージング」の差分です。ステージ後の変更は git diff には表示されません。ステージ後の差分を見るときは git diff --staged を使いましょう。

4-3. コミット単位で見る(git show)

ターミナル
# 直前のコミットの内容(メッセージ+差分)を表示
$ git show

# 特定のコミットを表示
$ git show a1b2c3d

4-4. 変更を元に戻す(restore)— 入門編

まだコミットしていない変更を捨てたい場合は git restore です。

ターミナル
# ファイルを最後のコミットの状態に戻す(未保存の編集が消える!)
$ git restore hello.txt

# ステージだけ取り消す(ファイルの中身はそのまま)
$ git restore --staged hello.txt
取り消しは取り返しがつかないことも git restore(作業ディレクトリの変更を捨てる)は、保存していなかった編集を永遠に失います。実行前に git diff で捨てる内容を確認する習慣をつけましょう。
第5章

リモートとGitHub — push / pull / clone

5-1. リモートリポジトリとは

ローカルリポジトリ(自分のPC)だけだと、PCが壊れたら履歴ごと消えます。また仲間と共同作業もできません。そこでリモートリポジトリ(GitHubなどネット上の共有保管庫)を使います。

  • push: ローカルのコミットをリモートへアップロード
  • fetch: リモートの最新履歴をダウンロード(作業中のファイルは変更しない)
  • pull: fetch + 自分のブランチへの取り込み(merge)
  • clone: リモートリポジトリを丸ごと手元に複製(最初の1回)

5-2. GitHubでリポジトリを作ってpushする

GitHubのトップページから New repository → 名前を付けて作成(最初は README の追加にチェックを入れず「空」でOK)。作成後に表示されるURLを使って、手元のリポジトリと紐づけます。

ターミナル
# my-project フォルダ内で実行
# リモートを origin という名前で登録
$ git remote add origin git@github.com:taro-yamada/my-project.git

# 登録の確認
$ git remote -v
origin  git@github.com:taro-yamada/my-project.git (fetch)
origin  git@github.com:taro-yamada/my-project.git (push)

# main ブランチを初回push(-u で「今後は origin/main と紐づく」と設定)
$ git push -u origin main

2回目以降は git push だけでOKです。

origin とは? リモートリポジトリの登録名です(URLの別名)。慣例で origin を使いますが何でも構いません。1つのローカルに複数のリモート(fork元と自分のforkなど)を登録することもあります。

5-3. 他人(または別PC)から取得する(git clone)

ターミナル
# リモートリポジトリを丸ごと複製(履歴含む)
$ git clone git@github.com:taro-yamada/my-project.git

# フォルダ名を変えて複製
$ git clone git@github.com:taro-yamada/my-project.git my-app

clone したリポジトリには origin が自動で登録されているので、いきなり git push ができます。

5-4. 日常の同期サイクル(共同作業の鉄則)

複数人で作業するときは、作業前には pull、作業後には push が鉄則です。

1日の流れ
# 朝:まず最新を取得
$ git pull

# 〜昼:普段どおり編集してコミット 〜
$ git add .
$ git commit -m "検索機能を修正"

# 夕方:push する前に、仲間の更新が入っていないかもう一度 pull
$ git pull
$ git push

5-5. fetch と pull の違い

git fetch はリモートの最新状況を「取得して確認するだけ」。作業中のファイルは一切変わりません。git pull は fetch に加えて自分のブランチに取り込む(マージする)まで行います。

安心して確認したいときは fetch 仕事中に「仲間が何をしたかだけ先に見たい」ときは git fetchgit log origin/main --oneline で確認してから git merge origin/main する、という段階的な進め方ができます。

5-6. HTTPS と SSH

方式URLの形認証
HTTPShttps://github.com/user/repo.gitブラウザ認証・Personal Access Token
SSHgit@github.com:user/repo.git第2章で登録したSSH鍵

どちらでも構いませんが、一度設定してしまえば手間が少ないのはSSHです。GitHubのリポジトリページの Code ボタンで両方のURLをコピーできます。

第6章

ブランチ — 履歴を分岐させて並行開発

ブランチとは

ブランチとは「コミット履歴の流れに付けた名前付きの矢印」です。技術的には、コミットハッシュを1つ指し示す41バイトの小さなファイルに過ぎません。

ブランチがあると何が嬉しいか?

  • main を壊さずに作業できる:新機能は必ず別ブランチで作り、完成してから main に合流させる。
  • 複数の作業を並行できる:バグ修正ブランチと新機能ブランチを同時に進められる。
  • 試作(スパイク)を気軽に捨てられる:うまくいかなければブランチごと削除して終わり。
イメージ
# main の歴史
... → A → B → C        # main は C を指している

# add-search ブランチを作ると、矢印がもう1本増えるだけ
main:    ... → A → B → C
add-search:           ↖(同じ C を指す)

# add-search 上でコミットすると、矢印が前に進む(main は動かない)
main:    ... → A → B → C
add-search:           ↖ → D → E

基本コマンド(現代版:switch を使おう)

ターミナル
# ブランチ一覧(現在位置に * が付く)
$ git branch
* main

# 新しいブランチ「add-search」を作成して移動(-c = create)
$ git switch -c add-search
Switched to a new branch 'add-search'

# 既存ブランチへの移動
$ git switch main

# ブランチを作るだけで移動しない
$ git branch fix-typo

# ブランチを削除(マージ済みのみ。未マージは -D)
$ git branch -d add-search

# ブランチ名の変更
$ git branch -m new-name
checkout と switch の関係 古い記事では git checkout -b add-search と書かれています。checkout は「ブランチ移動」も「ファイルの復元」も兼ねた多機能コマンドでしたが、役割が紛らわしいため、Git 2.23 で switch(ブランチ移動専用)restore(ファイル復元専用)に分割されました。この教科書では新コマンドを使います。

命名の慣習

接頭辞用途
feature/新機能の開発feature/login
fix/バグ修正fix/crash-on-startup
hotfix/緊急修正hotfix/security-patch
docs/ドキュメントのみdocs/readme

HEAD と detached HEAD

HEAD は「いま自分がいる位置」の目印です。通常はブランチを指していて、コミットするとブランチが進みます。しかし git switch a1b2c3d のようにコミットハッシュを直接指定して移動すると、HEAD がどのブランチも指さない「detached HEAD」状態になります。

ターミナル
$ git status
HEAD detached at a1b2c3d   # ← この状態は「見るためだけ」の位置にいる

# この状態でコミットすると、ブランチに属さない"迷子のコミット"になる
detached HEAD になったら 過去を見に来ただけなら git switch main で戻ればOK。ここで作業したくなったらまずブランチを作ってからコミットしましょう(git switch -c work-here)。作らないままコミットして移動すると、そのコミットは最終的にGCで消えます。
第7章

マージとコンフリクト解決

7-1. マージの仕組み

ブランチで作った変更を本体に取り込む操作がマージ(merge)です。

ターミナル
# ① まず取り込む「先」に移動する(feature を main に入れたいなら main へ)
$ git switch main

# ② マージする
$ git merge add-search

マージには2パターンあります。

種類条件結果
Fast-forward分岐後に main 側に新コミットがない矢印を先に進めるだけ。マージコミットは作られない
三方マージ(three-way)両側に新コミットがある「マージコミット」が新しく作られ、2つの流れが合流する

履歴で確認すると分かりやすいです。

ターミナル
$ git log --oneline --graph --all
*   f8e9d0c (HEAD -> main) Merge branch 'add-search'
|\
| * e4d5c6b 検索ボックスを追加
| * d3c2b1a 検索ロジックを実装
* | c2b1a0z READMEを更新       # ← main 側でも進んでいた
|/
* b1a0z9y 最初のコミット
--no-ff という選択 Fast-forward できるときでも、必ずマージコミットを作り「この機能はここまでが1つの塊」と履歴に残す派閥もあります: git merge --no-ff add-search。チームのルールに従いましょう。

7-2. コンフリクト(衝突)とは

2つのブランチで同じ行を別々に変更すると、Gitはどちらを採用すべきか判断できません。これがコンフリクトです。エラーではなく「人間に判断を求めている」状態なので、恐れません。

コンフリクト発生時
$ git merge feature-b
Auto-merging app.js
CONFLICT (content): Merge conflict in app.js
Automatic merge failed; fix conflicts and then commit the result.

7-3. 解決の手順(暗記しましょう)

① 状態確認② ファイルを手で直す③ add して解決を伝える④ commit でマージ完了

コンフリクトしたファイルの中身
$ cat app.js
<<<<<<< HEAD
const title = "私のバージョンのタイトル";
=======
const title = "仲間のバージョンのタイトル";
>>>>>>> feature-b
マーカー意味
<<<<<<< HEAD=======自分側(マージ先)の変更
=======>>>>>>> feature-b相手側(マージ元)の変更

この <<< などのマーカー行を消し、「最終的にこうあるべき」状態に手で編集します(片方を採用してもいいし、両方を組み合わせてもいい)。

解決の操作
# ② エディタで app.js を正しい状態に直した後…

# ③ 「このファイルは解決した」と Git に教える
$ git add app.js

# コンフリクトが全部解決したか確認(全ファイルがステージ済みになっているはず)
$ git status

# ④ マージコミットで完了(エディタが開いたらそのまま保存でOK)
$ git commit
マーカーが残ったままコミットしない <<<<<<< がファイルに残ったままだとプログラムは動きません。VS Code や JetBrains はコンフリクト専用の GUI(「両方の変更を取り込む」ボタンなど)を提供しているので、活用しましょう。

7-4. マージをやめたいとき

ターミナル
# コンフリクトを解決するのをやめて、マージ前の状態に戻す
$ git merge --abort

# コンフリクトが少ないときは VS Code で直すのが最速
$ code .   # VS Code でフォルダを開く

7-5. コンフリクトを減らす工夫

  • 小さく・短い単位でマージする(長寿命ブランチを作らない)
  • pull はこまめに(放置すると差が大きくなり衝突しやすい)
  • 同じファイルの同じ領域を複数人で同時に触らない役割分担にする
第8章

取り消し・訂正の技術 — reset / revert / reflog

「間違えてコミットした!」「やっぱりこの変更は無しにしたい!」は日常です。状況別の対処法を一気に覚えましょう。

8-1. 状況別チャート

やりたいことコマンド
コミットメッセージを間違えた(まだpushしていない)git commit --amend -m "正しいメッセージ"
コミットし忘れたファイルがある(同上)git add 忘れファイルgit commit --amend --no-edit
直前のコミットをなかったことにしたい(変更も捨てる)git reset --hard HEAD
直前のコミットを取り消すが変更は残したいgit reset --soft HEAD^
2つ以上前のコミットを取り消したいgit reset --soft HEAD~2(数字で戻る個数)
push済みのコミットを安全に打ち消したいgit revert <ハッシュ>

8-2. reset の3つのモード

git reset は「指定したコミットまで歴史を巻き戻す」コマンドで、どこまで変更を残すかをモードで選びます。

モード履歴ステージ作業ディレクトリ用途
--soft戻す残る残るコミットをやり直したい(再コミット前提)
--mixed(既定)戻す空にする残るコミットも add もやり直したい
--hard戻す空にする消える全部なかったことにしたい
--hard は最終兵器 git reset --hard は未コミットの変更を永久に破棄します。実行前に git status で捨てるものを確認。仲間と共有済みのコミットに対して reset + force push をすると履歴を壊すのでNGです(→ 8-3 の revert を使う)。

8-3. revert — 「打ち消しコミット」で安全に取り消す

git revert は、指定コミットの変更を打ち消す逆向きのコミットを新しく作る方法です。履歴を書き換えないので、push済みでも仲間がいる状態でも安全です。

ターミナル
# 特定のコミットを打ち消す
$ git revert a1b2c3d

# 直前のコミットを打ち消す
$ git revert HEAD

# マージコミットを打ち消す(main-line 1 は「1つ目の親」の意味)
$ git revert -m 1 f8e9d0c
resetrevert
履歴書き換える(消える)残る(打ち消しコミットが増える)
push済みコミット原則NG(force pushが必要)OK
向いている場面自分だけの未pushの作業共有後の取り消し

8-4. reflog — 最後の砦

「reset --hard で間違えて消しちゃった…」でも、多くの場合救出できます。GitはHEADが辿った移動履歴reflog に記録しているからです。

ターミナル
$ git reflog
a1b2c3d HEAD@{0}: reset: moving to HEAD^
d4e5f6g HEAD@{1}: commit: 重要な作業をコミット    # ← 戻りたい場所
a1b2c3d HEAD@{2}: commit: 別のコミット

# 消えたはずのコミット d4e5f6g へ戻る
$ git reset --hard d4e5f6g

reflog の記録は既定で90日間保持されるので、「Gitで消したはずのもの」はだいたい復旧できます。焦らず落ち着いて。

8-5. amend — 直前コミットの訂正

ターミナル
# メッセージだけ修正
$ git commit --amend -m "タイポ修正: recieve → receive"

# add し忘れたファイルを直前のコミットに混ぜる
$ git add forgot.txt
$ git commit --amend --no-edit
amend は push 前だけ amend はコミットを「別のコミットに置き換える」操作です。push済みのコミットを amend すると履歴が食い違い、pushできなくなります。push後は revert(または新しいコミット)で対応しましょう。
第9章

stash — 作業の途中で別の用事が入ったとき

こんな場面で

機能を開発中、まだコミットしたくない変更がある状態で「緊急のバグ修正をお願いしたい」…。コミットするには早すぎる変更を一時退避(セーブして棚上げ)するのが git stash です。

ターミナル
# 現在の変更(ステージ済み含む)を退避して、作業ディレクトリをきれいにする
$ git stash
Saved working directory and index state WIP on main: a1b2c3d ...

$ git status
nothing to commit, working tree clean   # ← きれいになった!

# 退避の一覧を見る
$ git stash list
stash@{0}: WIP on main: a1b2c3d ...

# 緊急作業をしてコミット…(省略)

# 退避した変更を復元する
$ git stash pop        # 復元 + 退避リストから削除(一番よく使う)

# または: 復元だけ(リストに残す)
$ git stash apply

# 退避を破棄
$ git stash drop stash@{0}
メッセージを付けておくと安心 git stash push -m "検索機能の途中経過" とすると、stash list にその文言が表示され、複数の退避があるときに分かりやすいです。

細かい使い方

コマンド動作
git stash未ステージ+ステージ済みの変更を退避
git stash -u新規ファイル(untracked)も退避する(既定では退避されない点に注意)
git stash pop最新の退避を復元してリストから削除
git stash pop stash@{1}指定番号の退避を復元
git stash branch new-branch退避を新しいブランチで復元(競合するときの抜け道)
stash は長期保管庫ではない stash はあくまで「数分〜数時間の棚上げ」用です。後で絶対必要な変更は、WIP(作業中)であることを明示したコミットを作る方が安全です。
第10章

実戦テクニック — .gitignore / tag / cherry-pick / bisect / blame

10-1. .gitignore — 管理しないファイルの指定

リポジトリのルートに .gitignore ファイルを置くと、指定したファイルをGitの管理対象外にできます。パスワード・APIキー・ビルド成果物・OSのゴミファイルなどは絶対にコミットしてはいけないので必ず設定します。

.gitignore の書き方の例
# コメント行
node_modules/      # ディレクトリごと除外(末尾スラッシュ)
*.log              # ワイルドカードで拡張子指定
build/             # ビルド成果物
.env               # 秘密情報(APIキーなど)
.DS_Store          # macOSのゴミファイル
Thumbs.db          # Windowsのゴミファイル

# ! で例外(除外の中の一部だけ含める)
!keep-this.log
すでに追跡済みのファイルには効かない 一度コミットしたファイルは .gitignore に書いても管理され続けます。管理をやめさせるには git rm --cached ファイル名 で追跡から外してコミットします(ファイル自体は残ります)。テンプレートは github/gitignore が便利です。

10-2. tag — リリースに目印を付ける

ターミナル
# 軽量タグ
$ git tag v1.0.0

# 注釈付きタグ(リリースはこちらが定番)
$ git tag -a v1.1.0 -m "検索機能を追加したリリース"

# タグ一覧・タグを指定してlog/show
$ git tag
$ git show v1.1.0

# タグは push されないので明示的に送る
$ git push origin v1.1.0
$ git push --tags

10-3. cherry-pick — 特定のコミットだけを持ってくる

「ブランチ全体は要らないけど、あの1コミットだけ欲しい」ときに、コミットをあるブランチから別のブランチへ移植します。

ターミナル
$ git switch main
$ git cherry-pick d3c2b1a
[main 9z8y7xw] 検索ロジックを実装    # ← 同じ変更が新しいコミットとして作られる

よくある用途:hotfixブランチで直したバグ修正を、他のリリースブランチにも適用したい。

10-4. bisect — バグを入れた犯人コミットを二分探索

「最近なんか壊れた」…数百コミットの中から原因を探すとき、git bisect二分探索で自動的に犯人を特定してくれます。

ターミナル
# 探索開始:現在(壊れている)と、最後に動いていた時点を教える
$ git bisect start
$ git bisect bad                 # 今は壊れている
$ git bisect good v1.0.0         # v1.0.0 の頃は動いていた

# Gitが中間のコミットに移動してくれる。動作確認して答える:
$ git bisect good   # または git bisect bad
# …を繰り返すと「d3c2b1a is the first bad commit」と特定してくれる

# 終了したら必ず元に戻す
$ git bisect reset

10-5. blame — この行は誰が書いた?

ターミナル
$ git blame app.js
a1b2c3d (Taro Yamada 2026-09-05 10:00:00 +0900 1) const version = "1.0";
e4d5c6b (Hanako Sato  2026-09-06 11:20:00 +0900 2) const title = "アプリ";

各行の最終変更者とコミットが分かります。犯人探しのためではなく「その変更の経緯(コミットメッセージ)を知るため」に使うのが健全な使い方です。VS Code なら行の右クリック →「Git Blame」、拡張機能 GitLens がおすすめです。

第11章

チーム開発の進め方 — Pull Request とブランチ戦略

11-1. GitHub Flow(最もシンプルな戦略)

小〜中規模のチームで最も広く使われているのが GitHub Flow です。「main は常にデプロイできる状態」を保ち、すべての作業をブランチ+Pull Requestで行います。

GitHub Flow のサイクル
# 1. main から新しいブランチを作る
$ git switch -c feature/login

# 2. 開発してコミットを積む
$ git add . && git commit -m "ログインフォームを追加"

# 3. push する
$ git push -u origin feature/login

# 4. GitHub で Pull Request を作成 → レビュー → 承認されたら main にマージ

# 5. マージ後、ローカルを整える
$ git switch main
$ git pull
$ git branch -d feature/login

11-2. Pull Request(PR)とは

PRは「このブランチを main に取り込んでください。レビューお願いします」という申請書です。コードの差分が表示され、行単位でコメントができ、承認(Approve)後にマージされます。

  • 良いPRの条件:小さい(1PR = 1目的)・タイトルと説明が具体的・スクショや動作確認方法を添える
  • レビューの観点:正しさ・読みやすさ・命名・テストの有無・設計の一貫性
  • レビューコメントは対人評価ではなくコードを良くするための情報として受け取る

11-3. マージ方法の選択(GitHubの3ボタン)

方法履歴向いている場面
Merge commitマージコミットが残る一般的なデフォルト。流れがそのまま見える
Squash and mergeブランチ内の複数コミットが1つに圧縮されるwipコミットだらけのとき。mainをきれいに保てる(人気)
Rebase and mergeコミットを main の先端に付け替える(マージコミットなし)線形な履歴にしたいとき

11-4. rebase との付き合い方

git rebase main(featureブランチ上で実行)は、「自分のコミットたちを main の最新の後ろに付け直す」操作です。merge の代わりにこれを使うと履歴が一直線になり、読みやすくなります。

よく使うrebase
# feature ブランチ上で: main の最新変更を自分の下に取り込む
$ git switch feature/login
$ git rebase main

# プッシュ済みブランチをrebaseした後は、履歴が変わっているので force push が必要
# (-u と --force-with-lease で安全に)
$ git push --force-with-lease origin feature/login
他人と共有中のコミットをrebaseしない rebaseはコミットを「つくり直す」操作です。自分専用のブランチならいくらでもOK。他の人が pull した可能性のあるブランチ(特に main)を rebase して force push すると、仲間の履歴が壊れます。絶対にやめましょう。

11-5. fork 型の流れ(OSS貢献など)

書き込み権限のないリポジトリに貢献するときは:

  1. GitHubでFork(自分のアカウント配下にコピー)
  2. fork を git clone
  3. ブランチを切って修正 → 自分のforkに push
  4. 本家リポジトリへ PR を出す(「fork元 → 本家」のPR)

企業内開発では「共有リポジトリに直接ブランチをpushする」形が多い(11-1のGitHub Flow)ですが、OSSではfork型が基本です。

11-6. 非常に大きなプロジェクトの戦略(知識として)

規模が大きいチームでは Git Flow(main + develop + feature/* + release/* + hotfix/*)や trunk-based development(短命ブランチ+feature flag)といった派生戦略もあります。まずは GitHub Flow に慣れ、チームの成長に合わせて選び直せばOKです。各戦略の詳細な比較や、レビュー・リリースの実践は第14章で扱います。

第12章

GitHub活用機能 — Issue / Projects / 保護ブランチ

前章までで「ブランチ → PR → マージ」の流れを学びました。この章ではその開発を支えるGitHubの機能を集めました。「コード以外のやり取り(課題・相談・レビュー・ルール)をGitHub上に集約する」と、チームの情報が1箇所に揃い、あとから「なぜそうなったか」も追跡できるようになります。

12-1. Issue — やるべきことを管理する

Issue(イシュー)は「バグ報告・改善したいこと・新機能のアイデア」を1件ずつ登録して議論する掲示板です。多くのチームでは、コードを書き始める前にまずIssueを立てるのが基本の流れです。

  • ラベル(Label): bug(バグ)/ enhancement(機能改善)/ question(質問)など、種類ごとに色を付けて分類
  • アサイン(Assignee): 担当者を明示する
  • マイルストーン(Milestone): 「v1.1リリース」など締切単位でIssueをまとめ、進捗を見る

Issueには #10 のような番号が自動で振られ、コミットやPRから参照できます。PR本文に fixes #10closes / resolves も同じ)と書くと、マージされた瞬間にIssue #10が自動でクローズされます。

① Issueを立てる
やること・困りごとを番号付きで記録
② ブランチ+コミット
コミットメッセージに #10 と書くとリンク
③ PR本文に fixes #10
レビュー・CIを経てマージ(→ 第13章)
④ Issueが自動クローズ
「やること」と「やったこと」が常に一致

12-2. Projects — カンバンボード

ProjectsはIssueを「Todo / In Progress / Done」などの列に並べて管理できるカンバンボードです。カード(Issue)をドラッグ&ドロップで動かせて、チームの「いま何をしているか」がひと目で分かります。小規模チームはまずIssueだけで十分ですが、並行タスクが増えてきたら導入を検討しましょう。

12-3. Draft PR — 途中経過も共有する

PRは完成品だけ出すものではありません。GitHubではDraft(ドラフト)PRとして「まだ作業中だけど方針を見てほしい」段階で出すことができます。

  • Draftの間はマージボタンが表示されず、「Ready for review」で完成に切り替える
  • 早い段階でレビュアーの意見をもらえるので、大きな手戻りを防げる
  • CIを走らせて「この方針でテストが通るか」を先に機械へ確認させる使い方も定番
PRは小さく・短期間で Draftを含めPRは数百行以内・1日〜数日で出し切るのが目安です。1000行を超えるPRはレビューされる可能性が急落します。大きくなりそうなら、先にレビューできる部分から分けて出しましょう(→ 14-5)。

12-4. 保護ブランチ — main を事故から守る

チーム開発ではmainへの直接pushを禁止し、必ずPR経由にするのが定番です。リポジトリの Settings → Branches(新しいUIでは Rules → Rulesets)で保護ルールを設定します。

設定効果
Require a pull request before merging直接pushを禁止し、必ずPR経由にする
Required approvalsレビューの承認(Approve)が指定人数分ないとマージできない
Require status checks to pass(→ 第13章)CIが成功していないとマージボタンが押せなくなる
Do not allow force pushes / deletions履歴の破壊(force push・ブランチ削除)を禁止
ルールは人に頼らず、設定に込める 「直接pushしないでね」と口頭で頼むより、保護ブランチで物理的に不可能にするのが現代的な運用です。ミスは必ず起きる前提で、仕組みで防ぎます。

12-5. CODEOWNERS — レビュアーを自動で指定する

.github/CODEOWNERS というファイルを置くと、「このパスの変更にはこの人のレビューが必須」という担当者の割り当てを自動化できます。保護ブランチと組み合わせると、指定メンバーの承認なしにはマージできなくなります。

.github/CODEOWNERS の例
# 書式: 対象パス  @ユーザー名(または @チーム名)

*                 @taro-yamada      # デフォルト: 全ファイルは Taro がレビュー
/frontend/        @hanako-sato      # frontend配下は Hanako が必須
/docs/            @taro-yamada @ken-tanaka   # docs配下はこの2人を指定

12-6. GitHub CLI(gh)— ターミナルからPRとIssueを操作

GitHub CLIgh コマンド)をインストールすると、ブラウザを開かずにIssueやPRを操作できます。普段のターミナル作業と同じ流れで開発が完結するのが魅力です。

ターミナル
# Issue を作る
$ gh issue create --title "検索が遅い" --body "大きなデータで3秒かかる"

# 現在のブランチからPRを作る(--fill はタイトル・本文をコミットから自動生成)
$ gh pr create --title "検索を高速化" --body "fixes #10" --fill

# 自分に関係するPRの状態やCIの結果を確認
$ gh pr status
$ gh pr checks

# 他人のPRを手元に持ってきて動作確認する
$ gh pr checkout 12

# レビューが通り次第マージ(ブラウザ不要)
$ gh pr merge --squash --delete-branch

第13章で扱うCIの結果も gh pr checks で確認できるので、覚えておくと強力です。

第13章

CI入門 — pushするたびに自動でテストする

13-1. CI(継続的インテグレーション)とは

CI(Continuous Integration)とは、pushやPRのたびに、サーバー側で自動的にビルド・テストを実行する仕組みです。「手元では動いたのに他人の環境では壊れている」「テストを忘れたままマージした」といった事故を、機械が毎回検証することで防ぎます。

① push / PR作成
開発者がコードを上げる
② CIが自動起動
GitHub Actions が検知して実行環境を準備
③ ビルド&テスト
きれいな環境で毎回ゼロから検証
④ 結果を通知
✓ 成功 / ✗ 失敗 をPRに表示

Gitの文脈でCIが重要なのは、「検証済みのコミットだけがmainに入る」状態を自動で作れるからです。

13-2. GitHub Actions の基本構造

GitHubにはGitHub ActionsというCI機能が組み込まれています(無料枠で十分試せます)。設定はリポジトリ内の .github/workflows/ 配下にYAMLファイルを置くだけで、構成要素は3つです。

要素意味
on:トリガー。いつ動くか(push / pull_request / 定期実行など)
jobs:処理のまとまり。複数並べると並列実行される
steps:ジョブ内の1手順。シェルコマンド(run)か既製パーツ(uses

13-3. 最初のworkflowを書いてみる

Node.jsプロジェクトで「push・PRのたびにテストを回す」最小構成の例です。

.github/workflows/ci.yml
name: CI

on:                      # トリガー: いつ実行するか
  push:
    branches: [main]
  pull_request:          # PRの作成・更新のたびに

jobs:
  test:
    runs-on: ubuntu-latest      # GitHubが用意する仮想マシン上で実行
    steps:
      - uses: actions/checkout@v4    # お決まり: リポジトリを取得する
      - uses: actions/setup-node@v4  # Node.js を準備
        with:
          node-version: 20
      - run: npm ci                  # 依存パッケージのインストール
      - run: npm test                # テスト実行(ここが失敗したら ✗)

このファイルをpushしてPRを出すと、PRページの Checks タブに実行結果が現れます。失敗した場合はログでどのstepで落ちたかが分かるので、修正してpushし直すと自動で再実行されます。

uses と run の違い run は「コマンドをそのまま実行」、uses は「世界中で共有されている既製のパーツ(Action)を再利用」。チェックアウトや言語のセットアップは毎回同じなので、ほとんどのプロジェクトが共通のActionを使います。

13-4. CIを「マージの条件」にする

CIがあっても、失敗していてもマージできてしまうなら効果が半減します。第12章の保護ブランチで「CIが緑(✓)でないとマージボタンが押せない」設定(Require status checks)をしておくと、品質ゲートが自動化されます。

  • PRページにCIの結果(✓ / ✗)が表示される
  • 失敗中はマージ不可 → 「CIが通るまでマージしない」がルールとして強制される
  • レビュアーは「コードを読む」ことに集中でき、動作確認の丸投げを防げる

13-5. CIでできることの広がり

用途やること
テスト実行基本。ユニットテスト・結合テストを毎回自動実行
静的チェックlint(構文チェック)や formatter(整形チェック)をCIで強制
ビルド確認少なくとも「ビルドが通る」ことを毎回保証
デプロイ(CD)mainにマージされたら本番・ステージングへ自動リリース
定期実行毎晩の依存パッケージ脆弱性チェックなど、cron相当の実行
CIは「テスト」を育ててこそ テストがほとんどないプロジェクトにCIを入れても「ビルドが通るか」しか保証できません。CIの価値はテストの数と質に比例します。まずは「壊れたらCIが必ず赤になる」小さなテストから始めましょう。
第14章

開発プロセス実践 — 戦略・レビュー・リリース

第11章ではGitHub Flowを学びました。この章では「自分のチームにはどの戦略が合うのか」「レビューをどう回すか」「リリースとバージョンをどう扱うか」という開発の進め方(プラクティス)をまとめます。

14-1. ブランチ戦略の比較と選び方

戦略構成向いているチーム
GitHub Flow(第11章)main + 短命な作業ブランチ。すべてPR経由小〜中規模。Webアプリなど継続的にデプロイする開発。まずはこれ
Git Flowmain(リリース用)+ develop(統合用)+ feature / release / hotfixバージョンを明確に束ねて出す製品(モバイルアプリ・組み込み・ライブラリなど)
trunk-based developmentmain直行に近い超短命ブランチ。未完成機能はfeature flagで隠す毎日複数回デプロイする成熟チーム。CI・テストが充実しているのが前提
  • 迷ったら GitHub Flow から始めて、痛みが出た箇所だけ足すのが定石
  • ブランチの寿命は短いほどよい(長寿命ブランチ = コンフリクトと手戻りの温床)
  • 戦略は「正解」ではなくチームの合意事項。守れない複雑なルールより、シンプルで守れるルールにする

14-2. コードレビューを回す技術

レビューは「欠点を探す場」ではなく「チームで知識を揃える最良の機会」です。続けるためのポイントを、出す側・見る側それぞれで。

PRを出す側レビューする側
小さく出す(1 PR = 1目的)速く返す(放置が一番の阻害要因。24時間以内が目安)
説明文に「何を・なぜ・どう確認したか」を書く指摘は提案形で(「ここは〇〇では?」)
出す前に自分でdiffを読み直す(セルフレビュー)好みの問題は nit:(細かい指摘)を付けて非ブロッキングに
動作確認のスクショ・手順を添える観点は「正しさ・読みやすさ・テスト・命名・設計の一貫性」
Approve は前進の合図 「改善の余地はあるが、今のままで正しい方向」なら Approve して先に進める判断も重要です。完璧主義のレビューは開発速度を殺します。逆に、返信がないままPRが放置されるのが最悪の状態なので、レビュー担当の割り当てを決めておくのも有効です。

14-3. Conventional Commits — コミットメッセージの統一ルール

Conventional Commitsは、メッセージの先頭に変更種別のプレフィックスを付ける広く使われているルールです。

メッセージの例
feat: 検索ボックスに候補表示を追加          # 新機能
fix:  ログアウト後にセッションが復活する問題を修正   # バグ修正
docs: READMEにセットアップ手順を追記        # ドキュメントのみ
refactor: 振る舞いを変えずに検索ロジックを整理      # リファクタリング
test: 検索APIのテストを追加               # テスト追加・修正
chore: 依存パッケージを更新               # ビルド・雑務
  • 履歴が git log --oneline で格段に読みやすくなる
  • 種別が機械判別できるので、CHANGELOGの自動生成やバージョン番号の自動決定につなげられる
  • PRの Squash and merge(11-3)と組み合わせると、mainの履歴がきれいに揃う

14-4. セマンティックバージョニングとリリース

セマンティックバージョニング(SemVer)は、バージョンを major.minor.patch(例: v2.3.1)の3つの数字で管理するルールです。

数字上げるタイミング
major後方互換性を壊す変更設定ファイルの形式を変更
minor後方互換を保った機能追加検索にフィルタ機能を追加
patchバグ修正(機能はそのまま)特定環境でのクラッシュを修正

リリース時には第10章で学んだタグを打ち、GitHubの Releases 機能でタグにリリースノート(変更点のまとめ)を添えて公開します。Conventional Commitsと組み合わせれば「featがあったらminorを上げる」といった判定も自動化できます。

14-5. ルールはリポジトリに文書化する

口頭や暗黙のルールは、メンバーが増えると必ず揺らぎます。次のようなファイルとしてリポジトリに入れておくと、新メンバーも同じ流れで開発できるうえ、ツールもそのルールに従って動いてくれます。

ファイル内容
CONTRIBUTING.md開発の流れ・ブランチ名の規約・PRのルール(貢献ガイド)
.github/PULL_REQUEST_TEMPLATE.mdPR作成時に説明欄のテンプレートを自動挿入
.github/CODEOWNERSレビュアーの自動指定(第12章)
AGENTS.mdAIエージェントに守らせるコーディング・運用ルール
プロセスも継続的に改善する ブランチ戦略・レビュー・リリースの運用は、一度決めたら固定ではなく振り返って直していく対象です。「このルール、実は誰も守っていない」と気づいたら、文書ごと更新してしまいましょう。
第15章

GitLab — GitHubと何が違うのか

これまでGitHubを前提に話してきましたが、Gitホスティングサービスは他にもあります。企業で採用例の多い GitLab を、GitHubとの対比で押さえておきましょう。まず安心してほしいのは、Gitのコマンドは1つも変わらないということです。変わるのは「Webサービス側の機能と名前」だけです。

15-1. GitLabとは

  • GitHubと同じく、Gitリポジトリのホスティング + Issue管理 + コードレビュー + CI/CDを提供するWebサービス
  • セルフホスト版(自社サーバーへの設置)が整っており、「ソースコードを外部クラウドに置きたくない」企業のオンプレ開発で人気
  • Issue → CI → デプロイまでを1つの製品で完結させるDevOpsプラットフォームを標榜している

15-2. 用語の対応表(これだけ覚えればOK)

GitHubGitLab備考
Pull Request(PR)Merge Request(MR)呼び方が違うだけ。やることは同じ
Issue・ラベル・マイルストーン同名・同じ概念操作感もほぼ同じ
Projects(カンバン)Issue BoardsIssueを列で並べて管理
GitHub ActionsGitLab CI/CD設定ファイルが違う(→ 15-3)
.github/workflows/*.yml.gitlab-ci.yml1つのファイルにまとめて書くスタイル
OrganizationsGroups / Subgroups階層化したグループ構造
保護ブランチ / CODEOWNERSProtected branches / CODEOWNERS同じ概念が同名で存在
ForkFork同じ
「Merge Request」という名前 PRもMRも本質は「マージしてくれ」という申請ですが、GitLabの名前の方が実態をストレートに表しています。「PR = MR」と脳内変換すれば、どちらに移っても怖くありません。

15-3. GitLab CI/CD をのぞいてみる

GitLabのCIは、リポジトリ直下の .gitlab-ci.yml 1ファイルに設定を書きます(GitHub Actionsで .github/workflows/ にYAMLを置くのと同じ発想です)。

.gitlab-ci.yml
stages:            # 実行順序の定義
  - test
  - deploy

run-tests:         # ジョブ名
  stage: test
  image: node:20   # 実行に使うDockerイメージ(Node.js 20環境)
  script:
    - npm ci
    - npm test

deploy-staging:
  stage: deploy
  script: ./deploy.sh staging    # 「mainのときだけ実行」などの制御も可能

MRを出すと自動でCI(パイプライン)が走り、結果がMRに表示されます。ここもGitHubと同じ「緑になるまでマージしない」運用ができます。

15-4. どちらを選べばいい?

状況有力な選択肢
個人・OSS・多様な外部連携GitHub(エコシステムが最大)
社外秘コードを自社サーバーで管理したいGitLab(セルフホスト)
Issue〜デプロイまで1製品で統一したいGitLab(DevOps統合)

そして最も大事な点:この教科書の第1〜11章で学んだGitそのもののスキルは、プラットフォームがどこであれ100%そのまま使えます。乗り換えで身につけ直す必要があるのは、PR/MRのUI操作とCIの設定ファイルくらいです。

第16章

トラブルシューティングFAQ

初心者が必ず踏む事故と、その対処法をQ&A形式でまとめました。折りたたみを開いて確認してください。

間違えて git add してしまった(まだコミットしていない)

ステージから外すだけなら:

$ git restore --staged ファイル名    # または git reset HEAD ファイル名

ファイルの中身はそのまま残ります。「add を取り消す」だけでコミットまで巻き戻るわけではありません。

git push したら rejected(non-fast-forward)と言われた

リモートに自分が持っていないコミットがある状態です。-f(force)は絶対に使わず、まず取り込みます:

$ git pull              # 衝突があれば解決してコミット
$ git push

履歴をきれいに保ちたい人は git pull --rebase を使う流儀もあります。

コミットメッセージを間違えたまま Enter を押してしまった

push していなければ git commit --amend -m "正しいメッセージ" で直せます。push 済みなら基本は我慢して修正コミットを積むか、チームで合意があれば amend + force push します。

直前のコミットから特定のファイルだけ外したい
$ git restore --staged ファイル名     # ステージから外す(amend 前)
$ git commit --amend --no-edit       # コミットを作り直す

作業ディレクトリの変更自体を消したい場合のみ git restore ファイル名(元に戻せないので注意)。

ブランチを削除してしまった! コミットを復活させたい

git reflog で失ったコミットのハッシュを探して:

$ git reflog
$ git switch -c restored-branch d4e5f6g   # そのハッシュから新しいブランチを作る

reflog に残っている限り(既定90日)ほぼ復旧できます。

巨大なファイル(動画・データセット等)を間違えてコミットした

直前コミットなら git reset --soft HEAD^git restore --staged ファイル.gitignore に追加 → 再コミット。何コミットも前で履歴から完全に消したい場合は git filter-repo や BFG Repo-Cleaner という専用ツールを使います(履歴の書き換えを伴うので、共有リポジトリではチームと調整が必須)。大容量バイナリは最初から Git LFS やクラウドストレージで管理しましょう。

warning: LF will be replaced by CRLF と表示される

WindowsとMacで改行コード(LF/CRLF)が違うことによる警告です。エラーではありません。第2章の git config --global core.autocrlf(Windows: true / Mac: input)を設定しておけば気にならなくなります。エディタや .editorconfig で改行コードを揃えるのが根本策です。

GitHub に push できない(Permission denied / 403)
  • SSH の場合: 第2章のSSH鍵登録を確認 → ssh -T git@github.com でテスト
  • HTTPS の場合: パスワードではなく Personal Access Token が必要(GitHubの Settings → Developer settings)
  • 権限のない他人のリポジトリに直接 push しようとしていないか → fork + PR の流れ(第11章)を使う
  • remote のURLが間違っていないか → git remote -v で確認、git remote set-url origin 正しいURL で修正
HEAD detached at ... と出て怖い

第6章で学んだ「ブランチを指さない HEAD」の状態です。見るだけなら git switch main で戻ればOK。この状態で作業したいときは先に git switch -c 新ブランチ名 を作ってからにします。

git pull したらコンフリクトだらけで動かなくなった

解決できないほど混戦なら、pull を一旦なかったことにできます:

$ git merge --abort          # マージ中なら中断
$ git rebase --abort         # rebase 中なら中断

以後は「pull はこまめに」「長生きブランチを作らない」で衝突の規模を小さく保つのが予防策です。

特定のコミットの状態を一度確認したい(一時的に過去へ)
$ git switch a1b2c3d        # detached HEAD でその時点のファイルが見える
$ git switch main           # 見終わったら戻る

「checkout」を多用する旧流儀の記事も多いですが、現代は switch / restore の使い分けが推奨です。

付録

コマンドチートシート

日常で使うコマンドの一覧です。ブラウザのページ内検索(Ctrl+F / +F)も活用してください。

基本のサイクル

コマンド説明
git initカレントディレクトリをリポジトリ化
git status現在の状態(変更・ステージ状況)を確認
git add ファイル名 / git add .変更をステージング(. は全部)
git commit -m "メッセージ"ステージ済み変更を履歴に記録
git restore ファイル未ステージの変更を破棄(最終コミットに戻す)
git restore --staged ファイルステージだけ取り消し

履歴・差分

コマンド説明
git log --oneline --graph --allコンパクトな履歴(グラフ付き)
git log -p ファイル差分つきの履歴
git diff未ステージの差分
git diff --stagedステージ済みの差分
git show コミットそのコミットの詳細
git blame ファイル行単位の変更者・コミット

リモート操作

コマンド説明
git clone URLリモートリポジトリを複製
git remote add origin URLリモートを origin として登録
git remote -vリモート登録の確認
git push -u origin ブランチpush(-u で上流設定)
git fetchリモートの最新を取得(変更しない)
git pullfetch + 取り込み

ブランチ・マージ

コマンド説明
git branchブランチ一覧
git switch -c ブランチ名ブランチを作成して移動
git switch ブランチ名ブランチを移動
git merge ブランチ名現在のブランチに取り込む
git merge --abortマージを中断して元に戻す
git branch -d ブランチ名ブランチ削除(強制は -D)
git rebase mainコミットを main の先端に付け直す

取り消し・訂正

コマンド説明
git commit --amend -m "…"直前コミットの訂正(push前限定)
git reset --soft HEAD^コミットだけ取り消し(変更は残る)
git reset --hard HEAD全部なかったことに(変更も消える)
git revert コミット打ち消しコミットを作る(push後も安全)
git reflogHEADの移動履歴(復旧の最後の砦)
git stash / git stash pop変更の一時退避 / 復元

応用

コマンド説明
git cherry-pick コミット特定コミットだけを移植
git bisect start / good / bad / reset二分探索でバグ混入コミットを特定
git tag -a v1.0 -m "…"注釈付きタグを作成
git push --tagsタグをリモートへ送信
git config --global …設定の変更

GitHub・運用(gh CLI / PR)

コマンド・書き方説明
gh issue createIssueを作成(第12章)
gh pr create --fill現在のブランチからPRを作成
gh pr checksPRのCI(ステータスチェック)を確認(第13章)
gh pr checkout 番号他人のPRを手元に取得して動作確認
gh pr merge --squash --delete-branchPRをSquashマージしてブランチも削除
fixes #番号(PR本文)マージ時に該当Issueを自動クローズ
最終章

総確認テスト — 14問

これまでの内容から14問出題します。選択肢をクリックするとその場で採点されます。間違えた問題は、該当章に戻って復習しましょう。

Q1. 編集したファイルを「次のコミットに含める」ために必要なコマンドは?

第3章の通り、変更は git add でステージングエリアに置かれ、その後 git commit で履歴に記録されます。

Q2. コミット履歴を1コミット1行でコンパクトに表示するオプションは?

git log --oneline が定番です。分岐も見たければ --graph --all を組み合わせます(第4章)。

Q3. リモートの最新を取得したいが、作業中のファイルは変えたくない。使うコマンドは?

git fetch は履歴の取得のみ。pull は fetch に加えて取り込み(マージ)まで行います(第5章)。

Q4. 新しいブランチ「feature/login」を作成してそこへ移動するコマンドは?

git switch -c で作成+移動(旧流儀では checkout -b)。git branch は作るだけ、merge は取り込みです(第6章)。

Q5. マージが Fast-forward になる条件は?

分岐後に main 側が進んでいなければ、矢印を前に進めるだけで済み、マージコミットは作られません(第7章)。

Q6. コンフリクトを解決した後、正しい手順は?

「手で直す → add で解決を伝える → commit でマージ完了」の4ステップです(第7章)。

Q7. すでにpush済みのコミットを安全に打ち消したい。最適なコマンドは?

revert は打ち消しコミットを追加するだけなので共有履歴を壊しません。reset や force push は仲間の履歴を破壊します(第8章)。

Q8. 未コミットの変更を一時退避して、作業ディレクトリを一時的にきれいにしたい。使うコマンドは?

git stash で退避、git stash pop で復元です。reset --hard は変更を消してしまうので用途が違います(第9章)。

Q9. 「過去の数百コミットの中から、バグが混入した最初のコミットを見つけたい」。便利なコマンドは?

git bisect が二分探索で犯人コミットを特定します。blame は「行単位の変更者調査」、cherry-pick は「コミットの移植」です(第10章)。

Q10. .gitignore の説明として正しいものは?

追跡済みのファイルは .gitignore に書いても管理され続けます。第10章の手順(rm --cached → コミット)が必要です。

Q11. PR本文に「fixes #10」と書いたときの動作は?

fixes / closes / resolves キーワードで、マージ時のIssue自動クローズが可能です。「Issue → ブランチ → PR → 自動クローズ」がGitHub開発の基本ループです(第12章)。

Q12. GitHub Actionsで「pushやPRのたびに自動テストを実行する」設定を置く場所は?

.github/workflows/ 配下にYAMLを置くだけで、on:(トリガー)→ jobs → steps の構成でCIが動きます。GitLabでは .gitlab-ci.yml 1ファイルに書きます(第13章・第15章)。

Q13. Conventional Commits で「バグ修正」を表すプレフィックスは?

fix: がバグ修正。feat: は新機能、docs はドキュメント、chore は雑務です。種別が機械判別できるのでCHANGELOGやバージョン自動化につなげられます(第14章)。

Q14. GitLabでGitHubの「Pull Request」に相当する機能の名前は?

Merge Request です。呼び方が違うだけで、レビュー・CI・マージの流れはPRと同じです。Gitのコマンド自体はプラットフォームが変わっても1つも変わりません(第15章)。
おわりに Gitは「読む」より「壊して慣れる」道具です。練習用リポジトリで reset や revert を何度も試して、取り返しの付け方を体で覚えるのが上達への近道です。お疲れさまでした 🎉