この教科書について
このWebアプリは、Gitを「まったく触ったことがない人」から「なんとなく使っている人」までを対象に、概念 → 手を動かす → 実戦の順で学べる教科書です。全部で19章あり、各章の末尾には「読了ボタン」、最終章には確認テストが用意されています。
この教科書の使い方
- 順番に読むのがおすすめです。前の章の内容が次の章の土台になっています。
- コードブロック右上の「コピー」ボタンでコマンドをコピーし、自分のターミナルで実際に打ってみてください。手を動かさないと身になりません。
- 読み進めた章の「読了」ボタンを押すと、左の目次に ✓ が付き、進捗が保存されます(ブラウザに記録されます)。
- 困ったときは左上の検索ボックスか、最後の「コマンドチートシート」「トラブルシューティングFAQ」へどうぞ。
- キーボードの ← → でも章を移動できます。
Gitとは? — バージョン管理の基本概念
こんな経験はありませんか?
レポートやソースコードを書いていて、こんなファイル名を使ったことはありませんか?
report_最終版.docx
report_最終版2.docx
report_最終版_提出用_修正済み.docx
report_最終版_提出用_修正済み_本当に最終.docx # ← もうどれが正しいのか分からない「前の状態に戻したい」「どこを変更したのか分からない」「仲間と同じファイルを編集して上書きし合った」——こうした問題をすべて解決するのがバージョン管理システムで、そのデファクトスタンダードが Git(ギット)です。2005年にLinuxの生みの親リーナス・トーバルズによって開発されました。
Gitでできること
- いつでも過去に戻れる:すべての変更履歴が保存されるので、好きな時点の状態を復元できます。
- 変更箇所が一目で分かる:誰が・いつ・どこを・なぜ変えたかが記録されます。
- 安全に並行開発できる:「ブランチ」機能で、本体を壊さずに実験的な変更ができます。
- 仲間と協力できる:GitHubなどのサービスを介して、複数人で同じプロジェクトを開発できます。
Gitは「スナップショット」を記録する
Gitはファイル全体の「差分」ではなく、コミットごとのスナップショット(その時点の全ファイルの状態)を記録します。変更されていないファイルは前のスナップショットへの参照が使われるため効率的です。この仕組みのおかげで「いつでもその時点の状態を丸ごと復元する」ことが高速にできるのです。
3つの「場所」を理解しよう — 最重要概念
Gitを使いこなす鍵は、ファイルが移動する3つの領域を理解することです。
いま実際に編集しているファイルの場所
(ステージング)
「次のコミットに入れる変更」を仮置きする場所
(確定・記録)
歴代のスナップショット(履歴)が保存される場所
なぜ「保存するだけ」でなく、間にステージングがあるのでしょうか? それは「コミットに含める変更を自分で選別する」ためです。10個のファイルを編集しても、関連する3つだけを選んで1つのコミットにまとめる、ということができます。
(アップロード)
(ダウンロード)
「分散型」バージョン管理とは
Gitは分散型です。各メンバーがリポジトリ(履歴ごと全部)を手元に持ちます。そのため:
- ネットに繋がっていなくても、履歴閲覧・コミット・ブランチ操作がすべてできる
- サーバー(GitHub)が障害を起こしても、誰かの手元に完全な履歴がある
- push/pull は「履歴のやり取り」なので、自由なタイミングで同期できる
まず覚えるべき用語
| 用語 | 意味 |
|---|---|
リポジトリ | 履歴を管理しているプロジェクトの保管庫(.git フォルダを含むディレクトリ) |
コミット | 変更を履歴に記録する操作、またはその記録された状態。いつでも戻れる「セーブポイント」 |
ブランチ | 履歴の流れを分岐させる機能。作業を互いに干渉せず並行して進められる |
HEAD | 「いま自分がどのコミット・ブランチにいるか」を指すポインタ |
ワークツリー | 実際にエディタで開いて編集しているファイル群(作業ディレクトリとほぼ同義) |
リモート | ネット上にある共有リポジトリ(GitHubなど)。慣例的に origin という名前で登録する |
環境構築と初期設定
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あわせて入れておくと便利な設定:
# 新しいリポジトリの既定ブランチ名を 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 --list2-3. GitHubアカウントとSSH接続(後で使う準備)
第5章以降でGitHubを使います。この機会にアカウント作成と、パスワード代わりになるSSH鍵の登録を済ませておきましょう。
- github.com でアカウントを作る。
- PCでSSH鍵ペア(秘密鍵・公開鍵)を生成する:
# 鍵ペアを生成(メールは自分のもの。パスフレーズは空でも可)
$ ssh-keygen -t ed25519 -C "taro@example.com"
# 公開鍵の中身を表示してコピーする
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1... taro@example.com- GitHub → Settings → SSH and GPG keys → New SSH key にコピーした公開鍵を貼り付けて保存。
- 接続テスト:
$ ssh -T git@github.com
Hi taro-yamada! You've successfully authenticated... # ← これが出れば成功id_ed25519(拡張子なし・.pubが付いていない方)が秘密鍵です。GitHubに登録するのは必ず公開鍵(.pub)の方。秘密鍵を誰かに送ったり、SNSやブログに載せたりしてはいけません。
基本のワークフロー — リポジトリ作成からコミットまで
いよいよ手を動かします。この章の流れはすべての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 presenthello.txt が Untracked 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.txtgit status の見方のまとめ:
| 表示 | 意味 | 対処 |
|---|---|---|
Untracked files | Gitがまだ管理していない新規ファイル | 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、ああああ —— 後から履歴を見ても何も分かりません。
3-5. 日常の基本サイクル
以上をまとめると、Gitでの普段の作業はこの繰り返しです。
コミットは小まめに。ゲームのセーブと同じで、细かくセーブしておくほど好きな場所に戻りやすいのです。
履歴を見る・比べる — 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 -p4-2. 変更差分を見る(git diff)
# 作業ディレクトリ(未ステージ)の変更を見る
$ git diff
# ステージ済みの変更を見る
$ git diff --staged
# 特定ファイルだけ
$ git diff hello.txt出力の読み方:
@@ -1 +1,2 @@
こんにちはGit
+Gitをはじめました # + が追加された行
-こんにちはWorld # - が削除された行git diff は「作業ディレクトリ vs ステージング」の差分です。ステージ後の変更は git diff には表示されません。ステージ後の差分を見るときは git diff --staged を使いましょう。
4-3. コミット単位で見る(git show)
# 直前のコミットの内容(メッセージ+差分)を表示
$ git show
# 特定のコミットを表示
$ git show a1b2c3d4-4. 変更を元に戻す(restore)— 入門編
まだコミットしていない変更を捨てたい場合は git restore です。
# ファイルを最後のコミットの状態に戻す(未保存の編集が消える!)
$ git restore hello.txt
# ステージだけ取り消す(ファイルの中身はそのまま)
$ git restore --staged hello.txtgit restore(作業ディレクトリの変更を捨てる)は、保存していなかった編集を永遠に失います。実行前に git diff で捨てる内容を確認する習慣をつけましょう。
リモートと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 main2回目以降は git push だけでOKです。
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-appclone したリポジトリには origin が自動で登録されているので、いきなり git push ができます。
5-4. 日常の同期サイクル(共同作業の鉄則)
複数人で作業するときは、作業前には pull、作業後には push が鉄則です。
# 朝:まず最新を取得
$ git pull
# 〜昼:普段どおり編集してコミット 〜
$ git add .
$ git commit -m "検索機能を修正"
# 夕方:push する前に、仲間の更新が入っていないかもう一度 pull
$ git pull
$ git push5-5. fetch と pull の違い
git fetch はリモートの最新状況を「取得して確認するだけ」。作業中のファイルは一切変わりません。git pull は fetch に加えて自分のブランチに取り込む(マージする)まで行います。
git fetchgit log origin/main --oneline で確認してから git merge origin/main する、という段階的な進め方ができます。
5-6. HTTPS と SSH
| 方式 | URLの形 | 認証 |
|---|---|---|
| HTTPS | https://github.com/user/repo.git | ブラウザ認証・Personal Access Token |
| SSH | git@github.com:user/repo.git | 第2章で登録したSSH鍵 |
どちらでも構いませんが、一度設定してしまえば手間が少ないのはSSHです。GitHubのリポジトリページの Code ボタンで両方のURLをコピーできます。
ブランチ — 履歴を分岐させて並行開発
ブランチとは
ブランチとは「コミット履歴の流れに付けた名前付きの矢印」です。技術的には、コミットハッシュを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-namegit 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 # ← この状態は「見るためだけ」の位置にいる
# この状態でコミットすると、ブランチに属さない"迷子のコミット"になるgit switch main で戻ればOK。ここで作業したくなったらまずブランチを作ってからコミットしましょう(git switch -c work-here)。作らないままコミットして移動すると、そのコミットは最終的にGCで消えます。
マージとコンフリクト解決
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 最初のコミット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 はこまめに(放置すると差が大きくなり衝突しやすい)
- 同じファイルの同じ領域を複数人で同時に触らない役割分担にする
取り消し・訂正の技術 — 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 | 戻す | 空にする | 消える | 全部なかったことにしたい |
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| reset | revert | |
|---|---|---|
| 履歴 | 書き換える(消える) | 残る(打ち消しコミットが増える) |
| 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 d4e5f6greflog の記録は既定で90日間保持されるので、「Gitで消したはずのもの」はだいたい復旧できます。焦らず落ち着いて。
8-5. amend — 直前コミットの訂正
# メッセージだけ修正
$ git commit --amend -m "タイポ修正: recieve → receive"
# add し忘れたファイルを直前のコミットに混ぜる
$ git add forgot.txt
$ git commit --amend --no-editstash — 作業の途中で別の用事が入ったとき
こんな場面で
機能を開発中、まだコミットしたくない変更がある状態で「緊急のバグ修正をお願いしたい」…。コミットするには早すぎる変更を一時退避(セーブして棚上げ)するのが 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 | 退避を新しいブランチで復元(競合するときの抜け道) |
実戦テクニック — .gitignore / tag / cherry-pick / bisect / blame
10-1. .gitignore — 管理しないファイルの指定
リポジトリのルートに .gitignore ファイルを置くと、指定したファイルをGitの管理対象外にできます。パスワード・APIキー・ビルド成果物・OSのゴミファイルなどは絶対にコミットしてはいけないので必ず設定します。
# コメント行
node_modules/ # ディレクトリごと除外(末尾スラッシュ)
*.log # ワイルドカードで拡張子指定
build/ # ビルド成果物
.env # 秘密情報(APIキーなど)
.DS_Store # macOSのゴミファイル
Thumbs.db # Windowsのゴミファイル
# ! で例外(除外の中の一部だけ含める)
!keep-this.loggit 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 --tags10-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 reset10-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 がおすすめです。
チーム開発の進め方 — Pull Request とブランチ戦略
11-1. GitHub Flow(最もシンプルな戦略)
小〜中規模のチームで最も広く使われているのが GitHub Flow です。「main は常にデプロイできる状態」を保ち、すべての作業をブランチ+Pull Requestで行います。
# 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/login11-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 の代わりにこれを使うと履歴が一直線になり、読みやすくなります。
# feature ブランチ上で: main の最新変更を自分の下に取り込む
$ git switch feature/login
$ git rebase main
# プッシュ済みブランチをrebaseした後は、履歴が変わっているので force push が必要
# (-u と --force-with-lease で安全に)
$ git push --force-with-lease origin feature/login11-5. fork 型の流れ(OSS貢献など)
書き込み権限のないリポジトリに貢献するときは:
- GitHubでFork(自分のアカウント配下にコピー)
- fork を
git clone - ブランチを切って修正 → 自分のforkに push
- 本家リポジトリへ 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章で扱います。
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 #10(closes / resolves も同じ)と書くと、マージされた瞬間にIssue #10が自動でクローズされます。
12-2. Projects — カンバンボード
ProjectsはIssueを「Todo / In Progress / Done」などの列に並べて管理できるカンバンボードです。カード(Issue)をドラッグ&ドロップで動かせて、チームの「いま何をしているか」がひと目で分かります。小規模チームはまずIssueだけで十分ですが、並行タスクが増えてきたら導入を検討しましょう。
12-3. Draft PR — 途中経過も共有する
PRは完成品だけ出すものではありません。GitHubではDraft(ドラフト)PRとして「まだ作業中だけど方針を見てほしい」段階で出すことができます。
- Draftの間はマージボタンが表示されず、「Ready for review」で完成に切り替える
- 早い段階でレビュアーの意見をもらえるので、大きな手戻りを防げる
- CIを走らせて「この方針でテストが通るか」を先に機械へ確認させる使い方も定番
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・ブランチ削除)を禁止 |
12-5. 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 CLI(gh コマンド)をインストールすると、ブラウザを開かずに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 で確認できるので、覚えておくと強力です。
CI入門 — pushするたびに自動でテストする
13-1. CI(継続的インテグレーション)とは
CI(Continuous Integration)とは、pushや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のたびにテストを回す」最小構成の例です。
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し直すと自動で再実行されます。
run は「コマンドをそのまま実行」、uses は「世界中で共有されている既製のパーツ(Action)を再利用」。チェックアウトや言語のセットアップは毎回同じなので、ほとんどのプロジェクトが共通のActionを使います。
13-4. workflow構文の応用 — needs / matrix / if / secrets
基本の形が分かったら、実務でよく使う4つの構文を押さえましょう。
| 構文 | できること |
|---|---|
needs: | ジョブに依存関係を付ける(lintが通ってからtest、など直列化) |
strategy.matrix | 1つのジョブを複数パターン(OS・バージョン)で自動複製する |
if: | 条件を満たすときだけ実行する(失敗時だけ、mainのときだけ、など) |
secrets | APIキーなどをリポジトリ設定から安全に渡す(コードには書かない) |
代表例がマトリクステストです。「複数OS × 複数バージョン」の組み合わせを、ジョブを量産せず一気に検証できます。
jobs:
test:
strategy:
matrix: # 組み合わせのリスト
os: [ubuntu-latest, macos-latest]
node: [18, 20]
runs-on: ${{ matrix.os }} # 組み合わせごとに実行環境が変わる
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
# → 2 OS × 2 バージョン = 4つのジョブが並列で走るneeds と if、secrets を組み合わせると、実務的なパイプラインになります。
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
test:
needs: lint # lint が成功したときだけ実行(失敗ならスキップ)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
- run: ./notify-slack.sh "$WEBHOOK_URL"
if: failure() # このstepだけ「失敗したとき」に実行
env:
WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} # シークレットはenv経由で渡す${{ secrets.名前 }} で参照します。コードやログに直接書くのは絶対NG。.gitignore(10-1)と同じ「秘密はリポジトリの外に置く」原則です。
13-5. 実行を速く・無駄なくする
CIはpushのたびにまっさらな環境で動くため、プロジェクトが大きくなると待ち時間が課題になります。定番の3つの工夫を知っておきましょう。
- キャッシュ:
setup-nodeにcache: npmを付けると依存パッケージがキャッシュされ、npm ciが大幅に速くなる - concurrency: 同じPRへ連続pushしたとき、古い実行をキャンセルして最新だけ回す
- paths フィルタ: ドキュメントだけの変更ならテストをスキップする、といった制御
on:
pull_request:
paths: # このパスに変更があるPRだけ実行
- "src/**"
- "package.json"
concurrency: # 同一ブランチの新しいpushで古い実行をキャンセル
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm # 依存パッケージをキャッシュ
- run: npm test13-6. CIが赤くなったら — 失敗の調べ方
CIは「壊れたことを教えてくれる存在」なので、赤くなること自体は正常です。落ち着いて次の手順で対処します。
- ログを読む: PRの Checks タブ → 失敗したジョブ → 落ちたstepのログを開く。エラー行の近くに原因が書いてあります
- ローカルで再現する: CIで動いているコマンド(
npm testなど)を手元で同じように実行してみる - 直してpush: PRは自動で再実行されます。「ネットワークの一時的な失敗」も疑わしいときは Re-run jobs ボタンでやり直し
13-7. CIを「マージの条件」にする
CIがあっても、失敗していてもマージできてしまうなら効果が半減します。第12章の保護ブランチで「CIが緑(✓)でないとマージボタンが押せない」設定(Require status checks)をしておくと、品質ゲートが自動化されます。
- PRページにCIの結果(✓ / ✗)が表示される
- 失敗中はマージ不可 → 「CIが通るまでマージしない」がルールとして強制される
- レビュアーは「コードを読む」ことに集中でき、動作確認の丸投げを防げる
13-8. CIでできることの広がり
| 用途 | やること |
|---|---|
| テスト実行 | 基本。ユニットテスト・結合テストを毎回自動実行 |
| 静的チェック | lint(構文チェック)や formatter(整形チェック)をCIで強制 |
| ビルド確認 | 少なくとも「ビルドが通る」ことを毎回保証 |
| デプロイ(CD) | mainにマージされたら本番・ステージングへ自動リリース |
| 定期実行 | 毎晩の依存パッケージ脆弱性チェックなど、cron相当の実行 |
開発プロセス実践 — 戦略・レビュー・リリース
第11章ではGitHub Flowを学びました。この章では「自分のチームにはどの戦略が合うのか」「レビューをどう回すか」「リリースとバージョンをどう扱うか」という開発の進め方(プラクティス)をまとめます。
14-1. ブランチ戦略の比較と選び方
| 戦略 | 構成 | 向いているチーム |
|---|---|---|
| GitHub Flow(第11章) | main + 短命な作業ブランチ。すべてPR経由 | 小〜中規模。Webアプリなど継続的にデプロイする開発。まずはこれ |
| Git Flow | main(リリース用)+ develop(統合用)+ feature / release / hotfix | バージョンを明確に束ねて出す製品(モバイルアプリ・組み込み・ライブラリなど) |
| trunk-based development | main直行に近い超短命ブランチ。未完成機能はfeature flagで隠す | 毎日複数回デプロイする成熟チーム。CI・テストが充実しているのが前提 |
- 迷ったら GitHub Flow から始めて、痛みが出た箇所だけ足すのが定石
- ブランチの寿命は短いほどよい(長寿命ブランチ = コンフリクトと手戻りの温床)
- 戦略は「正解」ではなくチームの合意事項。守れない複雑なルールより、シンプルで守れるルールにする
14-2. Git Flow を具体的に見る
14-1の表で名前だけ出した Git Flow は、5種類のブランチに役割を分ける、より厳格な戦略です。「リリース」という区切りがはっきりしている製品開発(モバイルアプリ・組み込み・配布するソフトウェア)で力を発揮します。
| ブランチ | 役割 | 流れ |
|---|---|---|
main | リリース済みの正式版のみ。タグを打つ場所 | 常設 |
develop | 次のリリースに向けた統合場所 | 常設 |
feature/* | 機能開発 | develop から切って develop へPR |
release/* | リリース直前の仕上げ(バージョン確定・最終微修正。機能追加はしない) | develop から切って、main と develop へ戻す |
hotfix/* | リリース済み版への緊急修正 | main から切って、main と develop へ戻す |
「v1.2をリリースする」ときの実際の手順はこのような流れです。
# 1. 普段は feature/* → develop へのPRを繰り返して機能を積む
# 2. リリース準備が整ったら release ブランチを切る
$ git switch -c release/v1.2 develop
# 3. バージョン番号を確定させ、リリース直前の微修正だけを積む
# 4. 完成したら main にマージしてタグを打つ
$ git switch main
$ git merge --no-ff release/v1.2
$ git tag -a v1.2.0 -m "Release v1.2.0"
# 5. 修正内容を develop にも戻す(次のリリースに引き継ぐ)
$ git switch develop
$ git merge --no-ff release/v1.214-3. コードレビューを回す技術
レビューは「欠点を探す場」ではなく「チームで知識を揃える最良の機会」です。続けるためのポイントを、出す側・見る側それぞれで。
| PRを出す側 | レビューする側 |
|---|---|
| 小さく出す(1 PR = 1目的) | 速く返す(放置が一番の阻害要因。24時間以内が目安) |
| 説明文に「何を・なぜ・どう確認したか」を書く | 指摘は提案形で(「ここは〇〇では?」) |
| 出す前に自分でdiffを読み直す(セルフレビュー) | 好みの問題は nit:(細かい指摘)を付けて非ブロッキングに |
| 動作確認のスクショ・手順を添える | 観点は「正しさ・読みやすさ・テスト・命名・設計の一貫性」 |
説明文の質をチームで揃えるには、PRテンプレート(.github/PULL_REQUEST_TEMPLATE.md、→ 14-6)が効率的です。PR作成時にこの内容が説明欄へ自動挿入されます。
## 何をしたか
(変更内容を1〜3行で)
## なぜやるか
(関連Issue: #10 など。背景・経緯)
## 確認方法
1. npm run dev で起動する
2. 検索ボックスで「あ」を入力する
3. 候補が表示され、矢印キーで選べることを確認
## スクリーンショット
(UIの変更なら Before / After)14-4. Conventional Commits — コミットメッセージの統一ルール
Conventional Commitsは、メッセージの先頭に変更種別のプレフィックスを付ける広く使われているルールです。
feat: 検索ボックスに候補表示を追加 # 新機能
fix: ログアウト後にセッションが復活する問題を修正 # バグ修正
docs: READMEにセットアップ手順を追記 # ドキュメントのみ
refactor: 振る舞いを変えずに検索ロジックを整理 # リファクタリング
test: 検索APIのテストを追加 # テスト追加・修正
chore: 依存パッケージを更新 # ビルド・雑務- 履歴が
git log --onelineで格段に読みやすくなる - 種別が機械判別できるので、CHANGELOGの自動生成やバージョン番号の自動決定につなげられる
- PRの Squash and merge(11-3)と組み合わせると、mainの履歴がきれいに揃う
慣れてきたら、スコープ(変更対象)や破壊的変更の明示も使ってみましょう。
feat(search): 候補表示にキーボード操作を追加 # (スコープ) で変更対象を明示
fix(login): セッションが残る問題を修正
feat!: 設定ファイルの形式をJSONからTOMLへ変更 # ! = 破壊的変更の印(major を上げる)14-5. セマンティックバージョニングとリリース
セマンティックバージョニング(SemVer)は、バージョンを major.minor.patch(例: v2.3.1)の3つの数字で管理するルールです。
| 数字 | 上げるタイミング | 例 |
|---|---|---|
major | 後方互換性を壊す変更 | 設定ファイルの形式を変更 |
minor | 後方互換を保った機能追加 | 検索にフィルタ機能を追加 |
patch | バグ修正(機能はそのまま) | 特定環境でのクラッシュを修正 |
リリース前の試験版は v1.3.0-beta.1 のようにプレリリース表記を使えます(正式版より「前」として扱うのがSemVerの仕様です)。
リリースの公開は、タグ(10-2)を打ったあとにGitHubの Releases で行います。ブラウザからでも、gh コマンドからでも作れます。
# 変更点のまとめ(リリースノート)を付けたリリースを作成
$ gh release create v1.3.0 --title "v1.3.0" --notes "検索フィルタ機能を追加"
# まず試験版を出すときは --prerelease を付ける
$ gh release create v1.3.0-beta.1 --prerelease --generate-notes14-6. ルールはリポジトリに文書化する
口頭や暗黙のルールは、メンバーが増えると必ず揺らぎます。次のようなファイルとしてリポジトリに入れておくと、新メンバーも同じ流れで開発できるうえ、ツールもそのルールに従って動いてくれます。
| ファイル | 内容 |
|---|---|
CONTRIBUTING.md | 開発の流れ・ブランチ名の規約・PRのルール(貢献ガイド) |
.github/PULL_REQUEST_TEMPLATE.md | PR作成時に説明欄のテンプレートを自動挿入 |
.github/CODEOWNERS | レビュアーの自動指定(第12章) |
AGENTS.md | AIエージェントに守らせるコーディング・運用ルール |
GitLab — GitHubと何が違うのか
これまでGitHubを前提に話してきましたが、Gitホスティングサービスは他にもあります。企業で採用例の多い GitLab を、GitHubとの対比で押さえておきましょう。まず安心してほしいのは、Gitのコマンドは1つも変わらないということです。変わるのは「Webサービス側の機能と名前」だけです。
15-1. GitLabとは
- GitHubと同じく、Gitリポジトリのホスティング + Issue管理 + コードレビュー + CI/CDを提供するWebサービス
- セルフホスト版(自社サーバーへの設置)が整っており、「ソースコードを外部クラウドに置きたくない」企業のオンプレ開発で人気
- Issue → CI → デプロイまでを1つの製品で完結させるDevOpsプラットフォームを標榜している
- エディションは無償で使えるCE(Community Edition)と高機能なEE(Enterprise Edition)があり、クラウド版(GitLab.com)は無料プランでも利用できる
15-2. 用語の対応表(これだけ覚えればOK)
| GitHub | GitLab | 備考 |
|---|---|---|
| Pull Request(PR) | Merge Request(MR) | 呼び方が違うだけ。やることは同じ |
| Issue・ラベル・マイルストーン | 同名・同じ概念 | 操作感もほぼ同じ |
| Projects(カンバン) | Issue Boards | Issueを列で並べて管理 |
| GitHub Actions | GitLab CI/CD | 設定ファイルが違う(→ 15-4) |
.github/workflows/*.yml | .gitlab-ci.yml | 1つのファイルにまとめて書くスタイル |
| Organizations | Groups / Subgroups | 階層化したグループ構造 |
| 保護ブランチ / CODEOWNERS | Protected branches / CODEOWNERS | 同じ概念が同名で存在 |
| Role(Read / Triage / Write / Maintain / Admin) | Role(Guest / Reporter / Developer / Maintainer / Owner) | 呼び名も権限の幅も少し違う |
| Fork | Fork | 同じ |
15-3. Merge Request の実務
MRもPRと同じ「ブランチ → 申請 → レビュー → マージ」ですが、GitLabならではの運用ポイントがあります。
- Draft MR: タイトル先頭に
Draft:を付けたMRはマージ不可になります(第12章のDraft PRと同じ発想。完成時に「Mark as ready」) - 承認(Approve)ルール: 「承認が何人必要か」「CODEOWNERSの承認を必須にするか」をプロジェクトごとに設定できる
- Squash commits オプション: マージ時にコミットを1つへ圧縮するかを、MRごとに選べる
- パイプライン連携: MRの中にCIの結果が表示され、「パイプラインが成功しないとマージできない」設定が可能(→ 15-4、15-5)
15-4. GitLab CI/CD をのぞいてみる
GitLabのCIは、リポジトリ直下の .gitlab-ci.yml 1ファイルに設定を書きます(GitHub Actionsで .github/workflows/ にYAMLを置くのと同じ発想です)。
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-5. GitLab CI/CD のもう一歩先
GitHub Actionsとの大きな違いは実行環境(Runner)です。GitHubはGitHub側が用意したマシンで動きますが、GitLabはクラウド版の共有Runnerを使うか、自分のサーバーにRunner(CIの実行エージェント)を登録して使うのが基本です。「CIも自社インフラで完結させたい」というオンプレ運用と相性が良い理由の1つです。
設定ファイルでよく使う構文は次のとおりです。
| 構文 | できること |
|---|---|
rules | ジョブを実行する条件(ブランチ・パイプラインの種類など)。旧 only / except の後継 |
variables | ジョブに渡す変数。機密情報は CI/CD 設定の変数として登録(masked(ログに隠す)/ protected(保護ブランチ限定)が選べる) |
cache | 依存パッケージなどをジョブ間でキャッシュ |
needs | ジョブの依存関係(stageの順番を待たずに先行実行させることもできる) |
environment | デプロイ先を「環境」として記録・可視化する |
run-tests:
stage: test
image: node:20
variables:
NODE_ENV: test
script:
- npm ci
- npm test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # MRのとき実行
- if: '$CI_COMMIT_BRANCH == "main"' # mainのときも実行
deploy-staging:
stage: deploy
script: ./deploy.sh staging
environment: staging # デプロイ先を「環境」として記録
rules:
- if: '$CI_COMMIT_BRANCH == "main"' # mainのときだけ実行この rules の条件分岐は、GitHub Actionsの on:(トリガー)と if:(実行条件)の役割を1か所に書くイメージです。MRのページにはパイプラインの進行状況が表示され、失敗していればマージボタンを無効化できます(15-3)。
15-6. どちらを選べばいい?
| 状況 | 有力な選択肢 |
|---|---|
| 個人・OSS・多様な外部連携 | GitHub(エコシステムが最大) |
| 社外秘コードを自社サーバーで管理したい | GitLab(セルフホスト) |
| Issue〜デプロイまで1製品で統一したい | GitLab(DevOps統合) |
そして最も大事な点:この教科書の第1〜11章で学んだGitそのもののスキルは、プラットフォームがどこであれ100%そのまま使えます。乗り換えで身につけ直す必要があるのは、PR/MRのUI操作とCIの設定ファイルくらいです。
トラブルシューティング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 pull | fetch + 取り込み |
ブランチ・マージ
| コマンド | 説明 |
|---|---|
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 reflog | HEADの移動履歴(復旧の最後の砦) |
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 create | Issueを作成(第12章) |
gh pr create --fill | 現在のブランチからPRを作成 |
gh pr checks | PRのCI(ステータスチェック)を確認(第13章) |
gh pr checkout 番号 | 他人のPRを手元に取得して動作確認 |
gh pr merge --squash --delete-branch | PRをSquashマージしてブランチも削除 |
fixes #番号(PR本文) | マージ時に該当Issueを自動クローズ |
総確認テスト — 14問
これまでの内容から14問出題します。選択肢をクリックするとその場で採点されます。間違えた問題は、該当章に戻って復習しましょう。
Q1. 編集したファイルを「次のコミットに含める」ために必要なコマンドは?
Q2. コミット履歴を1コミット1行でコンパクトに表示するオプションは?
--graph --all を組み合わせます(第4章)。Q3. リモートの最新を取得したいが、作業中のファイルは変えたくない。使うコマンドは?
Q4. 新しいブランチ「feature/login」を作成してそこへ移動するコマンドは?
Q5. マージが Fast-forward になる条件は?
Q6. コンフリクトを解決した後、正しい手順は?
Q7. すでにpush済みのコミットを安全に打ち消したい。最適なコマンドは?
Q8. 未コミットの変更を一時退避して、作業ディレクトリを一時的にきれいにしたい。使うコマンドは?
Q9. 「過去の数百コミットの中から、バグが混入した最初のコミットを見つけたい」。便利なコマンドは?
Q10. .gitignore の説明として正しいものは?
Q11. PR本文に「fixes #10」と書いたときの動作は?
Q12. GitHub Actionsで「pushやPRのたびに自動テストを実行する」設定を置く場所は?
.gitlab-ci.yml 1ファイルに書きます(第13章・第15章)。Q13. Conventional Commits で「バグ修正」を表すプレフィックスは?
Q14. GitLabでGitHubの「Pull Request」に相当する機能の名前は?