STEP 0
準備
Gitを入れて、最初の設定をすませる
目安 1〜2日
このステップの到達点 ── 自分のパソコンで git --version が表示され、名前とメールアドレスの設定が終わり、GitHubのアカウントを持っている状態。ここは学習ではなくただの準備作業 です。つまずいても実力とは関係ありません。
Gitとは何か
Gitは、ファイルの変更履歴を記録し、いつでも過去に戻れるようにする仕組み です。文書作成でいえば、「上書き保存」ではなく「その時点の状態に名前を付けて全部とっておく」道具だと考えてください。
Gitを使わない現場では、こういうファイルが必ず生まれます。
Gitを使わないと起きること 企画書.docx
企画書_修正.docx
企画書_修正2.docx
企画書_最終.docx
企画書_最終_田中修正.docx
企画書_ほんとの最終.docx ← どれが最新か誰にもわからない
Gitを使うとファイルは 企画書.docx の1つだけになり、そのかわりに変更の履歴が裏側にすべて残ります 。「3日前の状態に戻す」「田中さんの変更点だけを見る」「2人の変更を1つに合わせる」がコマンド1つでできるようになります。
GitとGitHubは別のもの
ここを混同したまま進む人がとても多いので、最初に整理しておきます。
※ たとえるなら、Gitがカメラ で、GitHubが写真を置いて共有するアルバムサービス です。カメラだけでも写真は撮れますが、人に見せるにはアルバムが要ります。
1. Gitを入れる
Windows ── 公式サイト git-scm.com から「Git for Windows」をダウンロードして実行します。設定項目がたくさん出てきますが、基本はすべて既定のまま「Next」で構いません 。ただし「Adjusting your PATH environment」の画面だけは、真ん中の推奨項目(Git from the command line and also from 3rd-party software)が選ばれていることを確認してください。インストールすると「Git Bash」という黒い画面のアプリも一緒に入ります。Windowsではこれを使うのがいちばん楽です。
Mac ── ターミナルで git --version と打つと、入っていない場合は開発者ツールの導入画面が出ます。指示に従えばそれで完了です。Homebrewを使っている人は brew install git のほうが新しい版が入ります。
2. きちんと入ったか確かめる
ターミナル / Git Bash コピー
git --version
実行結果(例) git version 2.47.1
数字が違っていてもかまいません。バージョンが表示されれば成功です。
3. 最初の設定(これをしないとコミットできません)
Gitは「誰が変更したか」を履歴に必ず記録します。そのため、最初に名前とメールアドレスを教えておく必要があります。--global は「このパソコン全体の設定」という意味で、最初の1回だけ 行えば十分です。
ターミナル(最初の1回だけ) コピー
git config --global user.name "Takayuki Ueki"
git config --global user.email "you@example.com"
# 新しいリポジトリの最初のブランチ名を main にする(現在の標準)
git config --global init.defaultBranch main
# 日本語のファイル名が文字化けして表示されないようにする
git config --global core.quotepath false
# 設定を確認する
git config --list
メールアドレスは公開されます コミットに書かれたメールアドレスは、GitHubに上げると誰でも見られる状態 になります。仕事以外で使う場合は、GitHubの設定画面(Settings → Emails)で発行される 12345678+username@users.noreply.github.com という形式の非公開アドレスを user.email に設定するのが安全です。
4. 改行コードの設定(日本のWindows利用者は要注意)
WindowsとMac・Linuxでは、行の終わりを表す見えない文字が違います。設定しないままチームで作業すると、1文字も直していないのにファイル全体が変更扱いになる という事故が起きます。
ターミナル コピー
# Windows の人
git config --global core.autocrlf true
# Mac / Linux の人
git config --global core.autocrlf input
5. GitHubのアカウントを作る
github.com にアクセスして無料アカウントを作ります。必要なのはメールアドレスとユーザー名だけです。ユーザー名は後で名刺代わりになります (URLが github.com/ユーザー名 になります)。ふざけた名前は避け、本名やハンドルネームなど、就職活動でも見せられるものにしておくのが無難です。
作成したら、必ず二要素認証(2FA) を設定してください。GitHubのアカウントは、あなたの書いたコードすべてへの鍵です。
6. 練習用のフォルダを用意する
ターミナル コピー
cd ~/Desktop # デスクトップに移動
mkdir git-practice # 練習用フォルダを作る
cd git-practice # その中に入る
pwd # 今いる場所を表示(Windowsでも Git Bash なら動きます)
フォルダの場所に注意 OneDrive・iCloud・Google ドライブなど同期がかかる場所にGitのリポジトリを置かないでください 。同期ソフトがGitの内部ファイルを勝手に書き換え、履歴が壊れる事故が実際に起きます。フォルダ名も、日本語や空白を含まない半角英数字にしておくと安全です。
ターミナルの基本コマンド cd フォルダ名(中に入る)、cd ..(1つ上に戻る)、ls(中身を一覧、Windowsのコマンドプロンプトでは dir)、pwd(今いる場所)。この4つだけ覚えておけば、Gitの学習には十分です。
練習問題
設定した名前とメールアドレスが正しく登録されているか、確認するコマンドを2つ書いてください。
解答を見る
ターミナル コピー
git config user.name
git config user.email
# まとめて見たいとき(どのファイルの設定かも表示される)
git config --list --show-origin
※ 何も表示されないときは、設定がまだ行われていません。STEP 0の3に戻ってください。
このステップは理解できた
STEP 1
基礎
最初のコミット ── 3つの場所を理解する
目安 3〜4日
このステップの到達点 ── git init でリポジトリを作り、add と commit で変更を記録できる。そして「なぜ add が必要なのか」を説明できる 。ここがGitのすべての土台です。
Gitには3つの場所がある
Gitがわかりにくいと言われる最大の理由は、ファイルの置き場所が3つ あることです。ここだけは図で覚えてください。
Gitの3つの場所 コピー
①作業ツリー ②ステージ ③リポジトリ
(自分が編集する場所) (記録する候補置き場) (確定した履歴)
file.txt を編集
│
│ git add file.txt
└──────────────▶ 記録する候補に入れる
│
│ git commit -m "説明"
└──────────────▶ 履歴として確定
◀────────────────────────────────────────
git log で見えるのは③だけ
「①で編集しただけ」ではGitは何も記録しません。②に入れて(add)、③に確定させる(commit) という2段階を踏んではじめて履歴に残ります。
なぜ2段階なのか 10か所直したうち、「この3か所だけを1つの記録としてまとめたい」という場面が実務では頻繁にあります。ステージがあるおかげで、変更を意味のあるまとまりに切り分けて記録できます 。この仕組みがGitの強みそのものです。
1. リポジトリを作る
リポジトリ とは、Gitが履歴を管理する単位のことです。ほぼ「1つのプロジェクトのフォルダ」だと思って構いません。
ターミナル コピー
cd ~/Desktop/git-practice
git init
実行結果 Initialized empty Git repository in /Users/you/Desktop/git-practice/.git/
このフォルダの中に .git という隠しフォルダができました。履歴はすべてこの中に入っています 。このフォルダを消すと履歴も消えます(逆に、Gitの管理をやめたいだけならこれを消せば普通のフォルダに戻ります)。
2. ファイルを作って、状態を見る
ターミナル コピー
echo "# 練習用リポジトリ" > README.md
git status
実行結果 On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
nothing added to commit but untracked files present (use "git add" to track)
Untracked files は「Gitがまだ知らないファイル」という意味です。git status は、迷ったらいつでも打ってよい安全なコマンド です。状態を表示するだけで、何も変更しません。実務でも1日に何十回も打ちます。
Gitは親切に次の一手を教えてくれる 上の出力の (use "git add ...") の部分に注目してください。Gitのメッセージには、次に何をすればよいかがほぼ必ず書かれています 。英語だからと読み飛ばす人と、読む人とで、上達の速さが決定的に変わります。
3. ステージに入れる(add)
ターミナル コピー
git add README.md # 1つのファイルを入れる
git add . # 今いる場所以下の変更をすべて入れる
git status
実行結果 On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.md
Changes to be committed(コミットされる予定の変更)に移りました。これがステージに入った状態です。
4. コミットする
ターミナル コピー
git commit -m "READMEを追加"
実行結果 [main (root-commit) 8f2a91c] READMEを追加
1 file changed, 1 insertion(+)
create mode 100644 README.md
8f2a91c のような文字列は、このコミットに付けられた固有の番号(コミットハッシュ) です。実際は40桁ありますが、頭7桁だけで指定できます。後で「あの時点に戻る」ときに使います。
5. 2回目以降のコミット
ターミナル(毎日くり返す流れ) コピー
echo "このリポジトリはGitの練習用です。" >> README.md
git status # ① 今どこが変わったか確認
git diff # ② 何がどう変わったか確認
git add README.md # ③ 記録する対象に入れる
git commit -m "READMEに説明文を追加" # ④ 記録を確定
git log --oneline # ⑤ 履歴を確認
git log --oneline の結果 c4d7e2b (HEAD -> main) READMEに説明文を追加
8f2a91c READMEを追加
この①〜⑤が、Gitを使う日々のすべてです。 この先のステップは、すべてこの流れの応用にすぎません。
6. コミットメッセージの書き方
メッセージは半年後の自分と、隣の席の人へのお手紙 です。「何をしたか」ではなく「なぜそうしたか 」まで書けると一人前です。
※ 1行目は50文字以内 で要約し、詳しい説明を書きたい場合は1行空けてから続けるのが世界共通の作法です。-m を付けずに git commit だけを実行すると、エディタが開いて複数行のメッセージを書けます。日本語のチームなら、メッセージも日本語で構いません。
1コミット=1つの意味 「ログイン修正」と「デザイン変更」と「タイプミス修正」を1つのコミットにまとめてはいけません。後から「デザイン変更だけを取り消したい」ということができなくなります。1つの意味のある変更ごとに、こまめにコミットしてください。 迷ったら、細かすぎるくらいが正解です。
練習問題
index.html と style.css の2つを編集しました。index.html の変更だけ をコミットし、style.css は次回に回したいとき、どう打ちますか。
解答を見る
ターミナル コピー
git add index.html # index.html だけをステージに入れる
git status # style.css がステージに入っていないことを確認
git commit -m "見出しの文言を修正"
# style.css の変更はそのまま残っている
git status
※ git add . を反射的に打つ癖がつくと、この使い分けができなくなります。add する前に必ず git status を見る 習慣をつけてください。
このステップは理解できた
STEP 2
基礎
履歴を読む ── log・diff・show
目安 2〜3日
このステップの到達点 ── 「いつ・誰が・どのファイルの・どこを変えたか」を自力で調べられる。Gitは記録するより、読むほうが実務では圧倒的に多く使います。
1. git log ── 履歴の一覧
ターミナル コピー
git log # 詳しく表示(q キーで終了)
git log --oneline # 1行ずつ、簡潔に
git log --oneline -5 # 最新の5件だけ
git log --oneline --graph --all # 枝分かれを図で表示(最頻出)
git log --stat # 変更されたファイルと行数も表示
git log -p # 変更内容そのものも表示
git log --author="Ueki" # 特定の人のコミットだけ
git log --since="2週間前" # 期間で絞る
git log --grep="ログイン" # メッセージで検索
git log -- src/main.js # 特定のファイルの履歴だけ
git log --oneline --graph --all の結果(例) * c4d7e2b (HEAD -> main) READMEに説明文を追加
* 8f2a91c READMEを追加
q が押せないと詰みます git log を打つと画面が切り替わり、キー入力を受け付けなくなったように見えることがあります。これは表示用の別プログラム(ページャ)が動いている状態で、q キーを押せば元に戻ります 。矢印キーやスペースキーで前後に移動できます。
2. HEAD という言葉
出力に出てきた HEAD -> main の HEAD(ヘッド) は、「今、自分がいる場所 」を指す目印です。ふつうは最新のコミットを指しています。
HEADを使った指定のしかた コピー
HEAD 今いるコミット(ふつうは最新)
HEAD~1 1つ前のコミット
HEAD~2 2つ前のコミット
HEAD~5 5つ前のコミット
8f2a91c ハッシュで直接指定してもよい
3. git diff ── 変更内容を見る(3種類)
ここでSTEP 1の「3つの場所」が効いてきます。どこと どこを比べるか で、打つコマンドが変わります。
※ --staged は --cached と書いても同じ意味です。古い資料では後者がよく使われています。
4. 差分の読み方
git diff の出力 コピー
diff --git a/README.md b/README.md
index 3b18e51..a1f9c33 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
# 練習用リポジトリ
-このリポジトリはGitの練習用です。
+このリポジトリはGitの学習用です。
+STEP 2まで進みました。
読み方は次のとおりです。この形式(unified diff)はGitに限らず、プログラミングの世界の共通語 なので、ここで覚えておくと後々ずっと得をします。
--- が変更前(a)、+++ が変更後(b)のファイル
@@ -1,2 +1,3 @@ は「変更前は1行目から2行分、変更後は1行目から3行分」という位置情報
- で始まる行が削除された行 、+ で始まる行が追加された行
記号のない行は、前後を示すための変わっていない行
1行だけ直しても「削除+追加」と表示される Gitは行単位で比較するため、行の途中を1文字直しただけでも「その行を消して、新しい行を足した」と表示されます。異常ではありません。単語単位で見たいときは git diff --word-diff が便利です。
5. git show ── 1つのコミットの中身を見る
ターミナル コピー
git show # 最新のコミットの内容
git show 8f2a91c # 指定したコミットの内容
git show HEAD~2 # 2つ前のコミットの内容
git show 8f2a91c:README.md # そのコミット時点のファイル全文を表示
6. git blame ── その行を書いた人を探す
「この謎の1行は誰がいつ何のために書いたのか」を調べるコマンドです。名前は「非難する」という意味ですが、実務では犯人捜しではなく、経緯を知るために使います 。
ターミナル コピー
git blame README.md
git blame -L 10,20 src/main.js # 10〜20行目だけ
実行結果(例) 8f2a91c (Takayuki Ueki 2026-08-14 10:02:11 +0900 1) # 練習用リポジトリ
c4d7e2b (Takayuki Ueki 2026-08-14 10:15:43 +0900 2) このリポジトリはGitの学習用です。
行頭のハッシュを git show に渡せば、その1行が生まれたときのコミットメッセージ(=理由) にたどり着けます。「消してよさそうに見えるコードを消す前に、blameで理由を確かめる」のは実務の基本動作です。
練習問題
「先週、田中さんが config.yml に加えた変更」を調べたいとき、どうやって探しますか。
解答を見る
ターミナル コピー
# ① まず候補のコミットを絞り込む
git log --author="Tanaka" --since="1週間前" --oneline -- config.yml
# ② 出てきたハッシュの中身を確認する
git show a3f9d21
# ③ 変更点だけまとめて見たいとき
git log -p --since="1週間前" -- config.yml
※ -- の後ろにファイル名を書くと「このファイルに関する履歴だけ」に絞れます。--author は名前の一部でも一致します。
このステップは理解できた
STEP 3
基礎
取り消しの技術 ── ここがGitの本当の価値
目安 4〜5日
このステップの到達点 ── 「やってしまった」場面で、状況に応じた正しい取り消し方を選べる 。Gitを使う最大の理由はここにあります。このステップだけは、必ず練習用リポジトリで実際に手を動かしてください。
まず、状況を切り分ける
取り消しコマンドが覚えられない原因は、「どの段階まで進んでしまったか」で使うコマンドが変わる ことにあります。次の表を、迷ったときの地図として使ってください。
1. git restore ── 編集をなかったことにする
ターミナル コピー
# ① まだ add していない編集を、最後のコミットの状態に戻す
git restore README.md
git restore . # すべてのファイルを戻す
# ② add したものをステージから降ろす(編集内容は消えない)
git restore --staged README.md
①は元に戻せません git restore ファイル名 は、コミットしていない編集を完全に捨てます 。Gitはまだその変更を知らないため、reflog(後述)でも救えません。実行前に必ず git diff で「本当に捨ててよい内容か」を確認してください。
古い資料では checkout と書かれています 以前はどちらも git checkout で行っていましたが、意味が多すぎて混乱の元だったため、Git 2.23以降で restore(ファイルを戻す) と switch(ブランチを切り替える) に分けられました。新しく学ぶなら、こちらを使ってください。
2. git commit --amend ── 直前のコミットをやり直す
ターミナル コピー
# メッセージだけ書き直す
git commit --amend -m "ログイン失敗時のエラー表示を修正"
# ファイルの入れ忘れを、直前のコミットに含める(メッセージは変えない)
git add forgot.js
git commit --amend --no-edit
「typo修正」だけのコミットが履歴に並ぶのは美しくありません。コミットした直後に気づいたら amend 、と覚えてください。
push した後の amend は原則禁止 amend は既存のコミットを作り直す(=ハッシュが変わる)操作です。すでに他人と共有した履歴に対して行うと、相手の手元と食い違い、混乱を招きます。共有済みの履歴は書き換えない 、これがGitの最重要ルールです。
3. git reset ── コミットを巻き戻す(3つのモード)
resetは強力で、しかも3つのモードで挙動がまったく違います 。ここは表で正確に覚えてください。
ターミナル コピー
# 直前のコミットを取り消すが、書いたコードは残す(いちばんよく使う)
git reset --soft HEAD~1
# 直前3つのコミットを1つにまとめ直したいとき
git reset --soft HEAD~3
git commit -m "ログイン機能を実装"
# 全部捨てて、最後のコミットの状態に完全に戻す(要注意)
git reset --hard HEAD
--hard は最後の手段 --hard は、書きかけのコードを問答無用で消します。実行前に git stash(STEP 10)で退避しておくと、後悔せずにすみます。「hardと打つ前に深呼吸」 を合言葉にしてください。
4. git revert ── 公開済みの変更を安全に打ち消す
すでにpushして他人と共有したコミットは、消してはいけません。かわりに「打ち消す内容の新しいコミットを積む」 のがrevertです。履歴は消えず、後から見ても「取り消した」という事実が残ります。
ターミナル コピー
git log --oneline
git revert c4d7e2b # 指定したコミットを打ち消すコミットを作る
git revert HEAD # 直前のコミットを打ち消す
git revert --no-commit c4d7e2b # 打ち消す内容を作るだけで、コミットはしない
revert 後の履歴 9b1c8e4 (HEAD -> main) Revert "READMEに説明文を追加"
c4d7e2b READMEに説明文を追加 ← 消えずに残っている
8f2a91c READMEを追加
5. git reflog ── 最後の命綱
--hard でコミットを消してしまっても、あきらめないでください。GitはHEADが動いた記録をすべて別に持っています 。これがreflogです。
実行結果(例) 9b1c8e4 HEAD@{0}: reset: moving to HEAD~1
c4d7e2b HEAD@{1}: commit: 消してしまった大事なコミット
8f2a91c HEAD@{2}: commit: READMEを追加
ターミナル(救出) コピー
git reset --hard c4d7e2b # 消したはずのコミットに戻る
# または、その状態を新しいブランチとして取り出す
git switch -c rescue c4d7e2b
「コミットさえしてあれば、まず救える」 一度でもコミットした内容は、reflogのおかげで約90日間は残っています。逆に言えば、コミットしていない編集は救えません。 不安な作業に入る前ほど、こまめにコミットしてください。これがGitでいちばん大事な習慣です。
練習問題
3日前にpushしたコミットに不具合が見つかりました。すでにチームの全員がそれを取り込んでいます。どう対処するのが正解ですか。また、なぜそれ以外の方法ではいけないのでしょうか。
解答を見る
ターミナル コピー
git log --oneline # 問題のコミットIDを特定する
git revert 7a2b9c1 # 打ち消すコミットを作る
git push origin main # ふつうに push できる(強制不要)
※ git reset --hard で消して --force で push すると、すでにそのコミットを持っている全員の手元と履歴が食い違い、チーム全体が混乱します。共有済みの履歴を書き換えない のが鉄則です。revertなら、他の人は普通に git pull するだけで済みます。
このステップは理解できた
STEP 4
基礎
.gitignore ── 入れてはいけないものを入れない
目安 2日
このステップの到達点 ── .gitignore を自分で書け、秘密情報・生成物・巨大ファイルをリポジトリに入れない 判断ができる。ここを知らずにGitHubに公開して事故を起こす人が、毎年たくさんいます。
入れてはいけないものは3種類
1. .gitignore を書く
リポジトリの一番上に .gitignore という名前のファイルを作り、無視したいものを1行ずつ書きます。
.gitignore コピー
# --- 秘密情報 ---
.env
.env.local
*.pem
*.key
credentials.json
# --- 依存パッケージ・生成物 ---
node_modules/
__pycache__/
*.pyc
.venv/
venv/
build/
dist/
*.log
# --- OS が勝手に作るファイル ---
.DS_Store
Thumbs.db
# --- エディタの設定 ---
.vscode/
.idea/
# --- データファイル(大きい・機微な情報を含む) ---
data/*.csv
!data/sample.csv # ただし sample.csv だけは例外的に管理する
2. 書き方のきまり
3. すでにコミットしてしまったファイルは無視されない
これが最大の落とし穴です。.gitignore は「これから追加されるファイル」にしか効きません。 一度コミットしてしまったファイルは、後から .gitignore に書いても管理され続けます。
ターミナル(管理からだけ外す) コピー
# --cached を付けると、Gitの管理から外れるだけで、手元のファイルは消えない
git rm --cached .env
git rm -r --cached node_modules/
echo ".env" >> .gitignore
git add .gitignore
git commit -m ".envをGit管理から除外"
--cached を忘れると、ファイル本体が消えます git rm .env と打つと、Gitの管理から外れるだけでなく、ディスク上のファイルそのものが削除されます 。無視したいだけのときは、必ず --cached を付けてください。
一度コミットした秘密情報は、消しても履歴に残ります 後のコミットで削除しても、過去のコミットを開けば誰でも読めます 。GitHubに上げてしまった場合は、履歴から消す作業より先に、そのキーやパスワードを無効化して作り直す(ローテーションする) のが最優先です。詳しくはSTEP 13で扱います。
4. 無視されているか確かめる
ターミナル コピー
git status --ignored # 無視されているファイルも含めて表示
git check-ignore -v .env # なぜ無視されたか、該当の行を表示する
git check-ignore -v .env の結果 .gitignore:2:.env .env
「.gitignoreの2行目の .env という指定によって無視された」という意味です。「書いたのに無視されない」と悩んだら、まずこれを打ってください。
5. 環境ごとの設定は .env.example で共有する
秘密情報そのものは共有できませんが、「どんな設定項目が必要か」は共有すべき です。値を空にした見本ファイルを置くのが定番のやり方です。
.env.example(これはコミットする) コピー
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
API_KEY=
SLACK_WEBHOOK_URL=
DEBUG=false
雛形はゼロから書かなくてよい GitHubには言語ごとの .gitignore の雛形が公開されています(github.com/github/gitignore)。GitHubでリポジトリを新規作成するときも、言語を選ぶだけで自動で用意されます。まず雛形を使い、足りないものを足す のが実務のやり方です。
練習問題
チームメンバーから「node_modules を .gitignore に書いたのに、まだ差分に出てくる」と相談されました。原因と、直す手順を答えてください。
解答を見る
原因は、.gitignore を書く前にすでにコミットされていた ためです。.gitignore は未追跡のファイルにしか効きません。
ターミナル コピー
git check-ignore -v node_modules/express # 何も出なければ「追跡済み」が原因
git rm -r --cached node_modules/ # 管理からだけ外す
git commit -m "node_modulesをGit管理から除外"
git push
※ この操作をpushすると、他のメンバーの手元でも node_modules がGitの管理から外れます。ファイル自体は各自の環境に残るため、実害はありません。
このステップは理解できた
STEP 5
応用
ブランチ ── 本線を壊さずに試す
目安 1週間
このステップの到達点 ── ブランチを作って作業し、本線に合流(マージ)できる。ここから先が「チームで働くためのGit」です。 ブランチを日常的に使えるかどうかが、初学者と実務者の境目になります。
ブランチとは何か
ブランチ(branch=枝) は、履歴を枝分かれさせて、本線に影響を与えずに作業するための仕組みです。
ブランチのイメージ コピー
┌─● E ── F ← feature/login(新機能を開発中)
│
A ── B ── C ── D ─┴──────────── ← main(いつでも動く状態を保つ)
▲
今ここ
・main は「完成していて、いつ動かしても大丈夫」な状態を保つ
・新しい作業は枝を伸ばして行い、完成したら main に合流させる
・失敗したら、枝ごと捨てれば main は無傷
実務では、mainブランチに直接コミットすることはほとんどありません 。「機能を1つ作る」「不具合を1つ直す」ごとにブランチを作り、完成したものだけをmainに合流させます。こうすることで、mainはつねに「そのまま公開できる状態」に保たれます。
1. ブランチを作って切り替える
ターミナル コピー
git branch # 今あるブランチの一覧(* が現在地)
git switch -c feature/login # 作成して、そこへ移動する(最頻出)
git switch main # main に戻る
git switch - # 直前にいたブランチに戻る
# 古い書き方(同じ意味。資料によく出てきます)
git checkout -b feature/login
git checkout main
git branch の結果 * feature/login
main
ブランチの正体は「付箋」です ブランチはフォルダのコピーではありません。「どのコミットを指しているか」を記録した、たった1行の付箋 にすぎません。だから作成も切り替えも一瞬で終わり、いくつ作っても容量をほとんど使いません。ブランチは気軽に作って、気軽に捨ててよいもの です。
2. ブランチの名前の付け方
チームでは名前の付け方が決まっていることがほとんどです。よく使われる形は次のとおりです。
※ 課題管理ツールと連携している現場では feature/123-user-login のように課題番号を入れる のが一般的です。日本語やスペースは使えないと考えてください。
3. ブランチで作業してコミットする
ターミナル コピー
git switch -c feature/login
echo "<h1>ログイン</h1>" > login.html
git add login.html
git commit -m "ログイン画面の雛形を追加"
git log --oneline --graph --all
実行結果 * 5e1a7d9 (HEAD -> feature/login) ログイン画面の雛形を追加
* c4d7e2b (main) READMEに説明文を追加
* 8f2a91c READMEを追加
ここで git switch main をしてフォルダを見てください。login.html が消えています。 驚くかもしれませんが、正常な動作です。mainブランチにはまだそのファイルが存在しないため、Gitが表示を切り替えているだけで、git switch feature/login で戻せば復活します。
4. マージする(合流させる)
マージは「取り込みたい側に移動してから」 行います。ここを間違える人が多いので注意してください。
ターミナル コピー
git switch main # ① 取り込む側(main)に移動する
git merge feature/login # ② feature/login を main に取り込む
git branch -d feature/login # ③ 用済みのブランチを消す
実行結果 Updating c4d7e2b..5e1a7d9
Fast-forward
login.html | 1 +
1 file changed, 1 insertion(+)
5. Fast-forward と マージコミット
マージには2つのパターンがあります。上の例に出てきた Fast-forward(早送り) は、mainが1歩も進んでいなかった場合に、単に付箋を前に進めるだけの動作です。
2つのマージのしかた コピー
【Fast-forward】main が進んでいない場合
before: A ── B ──● C (main)
└─ D ── E (feature)
after: A ── B ── C ── D ── E (main, feature) ← 枝分かれの跡が残らない
【マージコミット】両方が進んでいる場合
before: A ── B ── C ── F (main)
└─ D ── E (feature)
after: A ── B ── C ── F ─── M (main) ← M が「合流の記録」
└─ D ── E ─┘
ターミナル コピー
# 早送りできる場合でも、あえて合流の記録を残す
git merge --no-ff feature/login
# 逆に、早送りできるときだけマージを許す(履歴を一直線に保ちたい現場向け)
git merge --ff-only feature/login
どちらがよいのか 現場によって方針が違います。--no-ff は「この機能はここからここまでで開発された」という単位が履歴に残るため、後から追いやすくなります。一方、履歴を一直線に保ちたい現場では --ff-only やリベース(STEP 10)を使います。自分で決めず、そのチームの流儀に合わせてください。
6. ブランチの整理
ターミナル コピー
git branch # 手元のブランチ一覧
git branch -a # リモートのものも含めて一覧
git branch --merged # すでにマージ済みのブランチ(消してよい候補)
git branch --no-merged # まだマージしていないブランチ
git branch -d feature/login # マージ済みのブランチを削除(安全)
git branch -D feature/login # 強制削除(マージしていなくても消す)
git branch -m new-name # 今いるブランチの名前を変える
ブランチは使い捨てが基本 マージが終わったブランチは、その日のうちに消してください。残しておくと、数か月後には「これは何のブランチだったのか」がわからないものが何十個も溜まります。履歴はコミットに残っているので、ブランチを消しても作業は消えません。
練習問題
feature/report で作業中に、本番で緊急の不具合が見つかりました。まずそちらを直さなければなりません。作業中のコードはまだコミットできる状態ではありません 。どうしますか。
解答を見る
ターミナル コピー
# ① 作業中の変更を一時的に退避する(STEP 10で詳しく扱います)
git stash push -m "レポート機能 作りかけ"
# ② main から緊急修正用のブランチを作って直す
git switch main
git pull
git switch -c hotfix/login-crash
# ... 修正して commit / push ...
# ③ 元の作業に戻る
git switch feature/report
git stash pop
※ 「とりあえず WIP(作業中)というメッセージでコミットしておく」というやり方も実務ではよく使われます。その場合は、後で git commit --amend や rebase -i で整理してからレビューに出します。
このステップは理解できた
STEP 6
応用
コンフリクト ── こわがらずに解決する
目安 3〜4日
このステップの到達点 ── コンフリクトのマーカーを読み、自分で解決してマージを完了できる。コンフリクトは故障ではなく、Gitが「ここは人間が判断して」と相談してきている状態です。
なぜコンフリクトが起きるのか
Gitは、2人が別々の場所を直した場合は自動で合わせてくれます。しかしまったく同じ行を、2人が別々に変更した 場合、どちらが正しいかは機械には判断できません。そこでGitは作業を止め、人間に判断を求めます。これがコンフリクト(衝突) です。
コンフリクトが起きる状況 コピー
┌─ 田中さん: 3行目を「価格: 1200円」に変更
共通の元 ─┤
└─ 自分 : 3行目を「価格: 980円」に変更
→ Gitは「3行目をどちらにすればいいか」わからない → コンフリクト
1. コンフリクトを実際に起こしてみる
練習用リポジトリで、わざと起こしてみましょう。安全な場所で1度でも経験しておくと、本番で慌てずにすみます。
ターミナル コピー
# 準備:main で price.txt を作る
git switch main
echo "価格: 1000円" > price.txt
git add price.txt && git commit -m "価格ファイルを追加"
# ブランチ側で変更
git switch -c feature/price
echo "価格: 980円" > price.txt
git commit -am "価格を980円に変更"
# main 側でも同じ行を変更
git switch main
echo "価格: 1200円" > price.txt
git commit -am "価格を1200円に変更"
# マージするとコンフリクトする
git merge feature/price
実行結果 Auto-merging price.txt
CONFLICT (content): Merge conflict in price.txt
Automatic merge failed; fix conflicts and then commit the result.
2. マーカーを読む
コンフリクトしたファイルを開くと、Gitが次のような目印を書き込んでいます。
price.txt(コンフリクト中) コピー
<<<<<<< HEAD
価格: 1200円
=======
価格: 980円
>>>>>>> feature/price
<<<<<<< HEAD から ======= まで … 今いる側(この場合はmain)の内容
======= から >>>>>>> feature/price まで … 取り込もうとしている側の内容
3. 解決する
解決とは、マーカーを含めて、あるべき最終形にファイルを書き直すこと です。どちらかを選んでもよいし、両方を残しても、まったく新しい内容にしてもかまいません。
price.txt(解決後) コピー
価格: 980円
マーカーの消し忘れが最悪の事故になります <<<<<<< や ======= を消し忘れたままコミットすると、そのままの文字列が本番のコードに混入します。解決後は必ず git diff で確認し、可能なら grep -rn "<<<<<<<" . で全体を検索してください。
ターミナル(解決を確定する) コピー
git status # まだ解決していないファイルが一覧される
git add price.txt # 「解決しました」という意思表示が add
git commit # メッセージは自動で用意される。そのまま保存でよい
解決中の git status You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: price.txt
4. 途中でやめる
「思ったより大変だ、いったん元に戻したい」というときは、マージ前の状態に完全に戻せます。この逃げ道を知っていれば、コンフリクトはこわくありません。
ターミナル コピー
git merge --abort # マージを中止して、始める前の状態に戻す
git rebase --abort # リベース中ならこちら
git cherry-pick --abort # チェリーピック中ならこちら
5. 片方を丸ごと採用する
ターミナル コピー
git checkout --ours price.txt # 今いる側(HEAD)の内容を採用
git checkout --theirs price.txt # 取り込む側の内容を採用
git add price.txt
ours と theirs は場面で入れ替わります マージ中は「ours=自分のブランチ」ですが、リベース中は逆になります (リベースは自分のコミットを相手の上に載せ直す操作のため)。機械的に覚えず、迷ったら必ずファイルを開いて中身で判断してください。
6. エディタで解決する
VS Codeでコンフリクトしたファイルを開くと、「現在の変更を取り込む/入力側の変更を取り込む/両方の変更を取り込む」というボタンが表示されます。実務ではこちらのほうが速く、間違いも減ります。コマンドで何が起きているかを理解したうえで、道具は楽なものを使ってください。
7. コンフリクトを減らす習慣
こまめにmainを取り込む ── 1週間放置したブランチは高確率で衝突します。毎朝 git pull して、自分のブランチにmainを取り込む習慣を
ブランチを長生きさせない ── 数日で終わる大きさに作業を切る
1つのファイルを複数人で同時に触らない ── 作業分担の時点で防げます
自動整形ツールの設定をチームでそろえる ── 人によってインデントが変わると、全行がコンフリクトします
練習問題
git pull したらコンフリクトが起き、10ファイルで衝突していました。中身を見ると、自分にはどう直すべきか判断できない箇所があります。どうするのが正しい行動ですか。
解答を見る
① まず git merge --abort でいったん元に戻します(慌てて中途半端に直すのがいちばん危険です)。② git log --oneline で、相手がその変更をした意図を確認します。③ それでもわからなければ、変更した本人に聞きます 。Gitの操作の問題ではなく、コードの仕様の問題だからです。
ターミナル コピー
git merge --abort # いったん中止
git log --oneline main..origin/main # 相手が何をしたのか確認
git log -p --author="Tanaka" -3 # 変更の意図を読む
※ コンフリクトの解決は技術ではなく判断 です。判断材料を持っていない人が独断で解決するのが、最も事故につながります。聞くことは恥ではありません。
このステップは理解できた
STEP 7
応用
GitHubに公開する ── remote・push・clone
目安 4〜5日
このステップの到達点 ── 自分のリポジトリをGitHubに置き、push と pull ができる。認証で困らない。ここまで来ると、作ったものを人に見せられるようになります。
リモートリポジトリとは
手元のリポジトリ(ローカル)に対して、インターネット上に置いた共有用のリポジトリをリモート と呼びます。慣習として、主となるリモートには origin(オリジン)という名前を付けます。
ローカルとリモートの関係 コピー
自分のパソコン GitHub
┌──────────────┐ ┌──────────────┐
│ ローカル │ ── push ──▶ │ origin │
│ リポジトリ │ ◀── pull ── │ (リモート) │
└──────────────┘ └──────────────┘
│ clone
▼
同僚のパソコン
1. 認証の準備(ここでつまずく人が最多)
GitHubは2021年からパスワードでのpushを廃止 しました。現在の選択肢は3つです。
A. GitHub CLI を使う場合(いちばん簡単) コピー
# Mac: brew install gh / Windows: winget install GitHub.cli
gh auth login
# → GitHub.com / HTTPS / ブラウザで認証、と選んでいくだけ
B. SSH鍵を使う場合(実務の定番) コピー
# ① 鍵を作る(メールアドレスは自分のもの。パスフレーズは設定推奨)
ssh-keygen -t ed25519 -C "you@example.com"
# → 保存先を聞かれたら Enter でよい
# ② 公開鍵(.pub のほう)の中身を表示してコピーする
cat ~/.ssh/id_ed25519.pub
# ③ GitHub の Settings → SSH and GPG keys → New SSH key に貼り付ける
# ④ つながるか確認する
ssh -T git@github.com
成功したときの表示 Hi username! You've successfully authenticated, but GitHub does not provide shell access.
秘密鍵は絶対に人に渡さない id_ed25519(.pub が付いていない ほう)が秘密鍵です。これは家の鍵と同じで、他人に渡した瞬間にあなたのアカウントが使われてしまいます。GitHubに登録するのは、必ず .pub が付いた公開鍵 のほうです。
2. GitHubにリポジトリを作る
GitHubの右上「+」→「New repository」から作ります。設定項目は次のとおりです。
Repository name ── 半角英数字とハイフンで(例: git-practice)
Public / Private ── 迷ったら Private 。後から公開に変えられます
Add a README file ── 手元にすでにリポジトリがある場合はチェックを外す (後述の理由)
3. 手元のリポジトリをGitHubにつなぐ
ターミナル コピー
# リモートを登録する(URLは自分のリポジトリのもの)
git remote add origin git@github.com:username/git-practice.git
# HTTPS の場合
# git remote add origin https://github.com/username/git-practice.git
git remote -v # 登録されたか確認
git push -u origin main # 初回の push
実行結果 Enumerating objects: 9, done.
Writing objects: 100% (9/9), 812 bytes | 812.00 KiB/s, done.
To github.com:username/git-practice.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
-u は何をしているのか -u(--set-upstream)は、「このローカルブランチは、あのリモートブランチと対応している」という関係を記録します。1度付ければ、2回目からは git push だけで済みます。
4. 日々の push と pull
ターミナル コピー
git push # 手元の変更をGitHubへ送る
git pull # GitHub側の変更を手元に取り込む
git fetch # 取り込まずに、最新情報だけ確認する
git fetch --prune # 消えたリモートブランチの情報も整理する
git push -u origin feature/login # 新しく作ったブランチを初めて送るとき
作業を始める前に必ず pull 朝いちばんに git pull する習慣をつけてください。古い状態のまま半日作業すると、コンフリクトの量が跳ね上がります。これだけで、Gitで困る場面の半分は減ります。
5. 他人のリポジトリを取ってくる(clone)
ターミナル コピー
git clone git@github.com:username/project.git
git clone https://github.com/username/project.git
git clone https://github.com/username/project.git myfolder # 別名で取り込む
git clone --depth 1 https://github.com/username/project.git # 最新だけ(軽い)
clone は「リポジトリをまるごと複製する」操作です。git init と git remote add が同時に済んだ状態になるので、いきなり作業を始められます。
6. push が拒否されたとき
よく出るエラー ! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:username/repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.
これは「リモート側に、あなたが持っていない変更があります 」という意味です。誰かが先にpushしたか、GitHub上でREADMEを作ったときに起きます。
ターミナル(正しい対処) コピー
git pull # まず相手の変更を取り込む
# (コンフリクトが出たら STEP 6 の手順で解決する)
git push # あらためて送る
ここで --force を使ってはいけません エラーを消したい一心で git push --force と打つと、リモートにあった他人の作業を丸ごと消し去ります 。実務で最も深刻な事故の1つです。押し返されたら、まずpullしてください。
7. READMEを書く
リポジトリの顔になるファイルです。GitHubではトップページに自動で表示されます。READMEのないリポジトリは、他人にとって存在しないのと同じ だと考えてください。
README.md コピー
# 売上集計ツール
毎月の売上CSVを読み込み、支店別の集計表を出力するツールです。
## 必要なもの
- Python 3.11 以上
## 使い方
pip install -r requirements.txt
python src/main.py data/sales.csv
## 設定
.env.example を .env にコピーし、APIキーを記入してください。
## 注意
- data/ の中身は機密情報のため、リポジトリには含めていません。
※ 最低限、①何をするものか ②動かすのに必要なもの ③実行コマンド ④注意点 の4つを書けば十分です。Markdown(.md)は、# で見出し、- で箇条書き、というごく簡単な記法です。
練習問題
手元で作ったリポジトリをGitHubに上げようとしたら、GitHub側で「Add a README file」にチェックを入れて作ってしまい、push が拒否されました。どう対処しますか。
解答を見る
ターミナル コピー
# 共通の祖先を持たない履歴同士なので、明示的に許可して合流させる
git pull origin main --allow-unrelated-histories
# コンフリクトが出たら README.md を整えて
git add README.md
git commit
git push -u origin main
※ そもそもの予防策は、手元にリポジトリがある場合、GitHub側では空のリポジトリを作る ことです(READMEやライセンスにチェックを入れない)。GitHubの作成画面には、そのための手順がそのまま表示されます。
このステップは理解できた
STEP 8
応用
プルリクエスト ── 変更を「提案」する
目安 1週間
このステップの到達点 ── プルリクエスト(PR)を作り、レビューを受け、マージまで完了できる。実務のGitHubは、9割がこの流れで回っています。
プルリクエストとは
プルリクエスト(Pull Request、略してPR) は、「私のブランチの変更を、あなたの本線に取り込んでください」というお願いの手続き です。Gitの機能ではなく、GitHubが提供している仕組みです(GitLabでは「マージリクエスト」と呼びます)。
PRを挟むことで、次のことができるようになります。
マージ前に他人の目が入る ── 不具合や設計の問題を、本線に入る前に見つけられる
変更の意図が記録に残る ── なぜこの変更が必要だったかが、後から読み返せる
自動テストを走らせられる ── 壊れたコードは、そもそもマージできない仕組みにできる(STEP 11)
1. PRを出すまでの流れ
ターミナル(毎回この流れ) コピー
# ① 最新の main から始める(ここが重要)
git switch main
git pull
# ② 作業用ブランチを作る
git switch -c feature/user-search
# ③ 作業してコミット(こまめに)
git add .
git commit -m "ユーザー検索の入力欄を追加"
# ④ GitHubへ送る
git push -u origin feature/user-search
push 後の表示 remote: Create a pull request for 'feature/user-search' on GitHub by visiting:
remote: https://github.com/username/repo/pull/new/feature/user-search
このURLをブラウザで開けば、そのままPR作成画面になります。GitHubのリポジトリページに出る「Compare & pull request」ボタンからでも同じです。
GitHub CLI なら、ターミナルだけで完結します コピー
gh pr create --title "ユーザー検索機能を追加" --body "一覧画面に名前での絞り込みを追加しました。"
gh pr list # PRの一覧
gh pr view --web # ブラウザで開く
gh pr status # 自分に関係するPRの状況
gh pr checkout 42 # 他人のPRを手元で動かしてみる
2. PRの説明文の書き方
レビューする人は、あなたの頭の中を知りません。「何を」より「なぜ」と「どう確認したか」 を書いてください。
PRの説明文(雛形) コピー
## 何をしたか
ユーザー一覧画面に、名前での絞り込み機能を追加しました。
## なぜ必要か
問い合わせ対応時に、一覧を目視で探すのに時間がかかっていたため。
関連: #123
## 動作確認したこと
- [x] 名前の一部で検索できる
- [x] 該当0件のときに「見つかりません」と表示される
- [x] 空欄のまま検索すると全件表示に戻る
## レビューで見てほしいところ
検索処理を画面側に書きましたが、サービス層に移すべきか迷っています。
## スクリーンショット
(画面の画像を貼る)
PRは小さいほどよい 1000行のPRは、誰も真剣に読めません(「LGTM」とだけ返されて終わります)。目安は変更400行以内 です。大きくなりそうなら、「土台を作るPR」「機能を足すPR」のように分けてください。レビューの質は、PRの小ささでほぼ決まります。
3. レビューを受けて直す
指摘を受けたら、同じブランチにコミットを追加してpushするだけ です。PRは自動で更新されます。新しくPRを作り直す必要はありません。
ターミナル コピー
git add src/search.js
git commit -m "レビュー指摘: 検索処理をサービス層に移動"
git push # PRに自動で反映される
レビューでのやりとりの作法 指摘する側はコードを批評するのであって、人を批評しない 。「なぜこんな書き方を?」ではなく「ここは○○のほうが読みやすいと思いますが、どうでしょう」。指摘される側は、直したら返信して閉じる 。無言で直すと、相手は反映されたか確認できません。「ここはこういう理由でこのままにします」と返すのも、立派な回答です。
4. マージの3つの方式
PRのマージボタンには3種類あります。チームの方針に従うのが原則 ですが、違いは理解しておいてください。
※ Squash and merge を採用している現場では、作業中のコミットメッセージが多少雑でも問題になりません(最後に1つにまとまるため)。かわりにPRのタイトルがそのまま履歴に残る ので、タイトルは丁寧に書いてください。
5. マージ後の後始末
ターミナル コピー
git switch main
git pull # マージされた内容を取り込む
git branch -d feature/user-search # 手元のブランチを削除
git fetch --prune # 消えたリモートブランチの情報を整理
※ GitHub側のブランチは、PR画面の「Delete branch」ボタンで消せます。リポジトリ設定でマージ後に自動削除 することもできます(Settings → General → Automatically delete head branches)。
6. フォークを使う場合
他人のリポジトリ(オープンソースなど)に、書き込み権限のない状態で貢献するときは、フォーク(fork) という手順を踏みます。相手のリポジトリを自分のアカウントに複製してから、そこにPRを送ります。
ターミナル コピー
# ① GitHub上で Fork ボタンを押す
# ② 自分のアカウントに複製されたものを clone する
git clone git@github.com:myname/awesome-project.git
cd awesome-project
# ③ 本家を upstream として登録しておく(本家の更新を取り込むため)
git remote add upstream https://github.com/original/awesome-project.git
git remote -v
# ④ 本家の最新を取り込む
git fetch upstream
git merge upstream/main
# ⑤ ブランチを切って作業し、自分のフォークへ push → 本家へPRを出す
git switch -c fix/typo-in-readme
git push -u origin fix/typo-in-readme
最初の一歩はタイポ修正から オープンソースへの貢献は難しそうに見えますが、ドキュメントの誤字修正や日本語訳の改善 は歓迎されることが多く、PRの練習として最適です。「good first issue」というラベルの付いた課題を探してみてください。
練習問題
PRを出して1週間放置していたら、「このブランチにはコンフリクトがあります(This branch has conflicts)」と表示され、マージできなくなりました。どう対処しますか。
解答を見る
ターミナル コピー
# ① 最新の main を手元に取り込む
git switch main
git pull
# ② 自分のブランチに main を取り込んで、手元で解決する
git switch feature/user-search
git merge main
# → コンフリクトを解決(STEP 6の手順)
git add .
git commit
# ③ push すればPRの表示も解消される
git push
※ GitHubの画面上にも「Resolve conflicts」ボタンがありますが、簡単なものだけに使ってください 。手元で解決すれば、動作確認までしてからpushできます。そもそもの予防策は、PRを1週間も放置しないこと です。
このステップは理解できた
STEP 9
実務
チーム開発の流れ ── GitHub Flow と作法
目安 1〜2週間
このステップの到達点 ── 課題(Issue)から始まり、ブランチ・PR・レビュー・マージ・リリースまでの一連の流れを、チームの一員として回せる 。ここからはコマンドではなく「進め方」の話です。
1. GitHub Flow ── いま最も広く使われている進め方
ブランチの運用方法にはいくつか流派がありますが、迷ったらGitHub Flow で間違いありません。規則はたった6つです。
GitHub Flow コピー
① main はつねに「いつでもリリースできる」状態を保つ
② 作業は必ず main から新しいブランチを作って行う
③ こまめにコミットし、こまめに push する
④ 完成したら(あるいは相談したくなったら)PRを出す
⑤ レビューを受け、自動テストを通す
⑥ main にマージし、すぐにリリースする → ブランチは削除
2. Issue(課題)から始める
実務では、いきなりコードを書き始めません。まず「何をするか」をIssueに書きます 。Issueは、やることリストであり、議論の場であり、記録でもあります。
Issueの例 コピー
## 概要
ログインに失敗しても、エラーメッセージが表示されない
## 再現手順
1. ログイン画面を開く
2. 存在しないメールアドレスを入力して「ログイン」を押す
3. 何も表示されず、画面がそのまま止まる
## 期待する動作
「メールアドレスまたはパスワードが違います」と表示される
## 環境
Chrome 131 / macOS 15.2
ターミナル(GitHub CLI) コピー
gh issue create --title "ログイン失敗時にエラーが出ない" --body "..."
gh issue list --assignee "@me" # 自分に割り当てられた課題
gh issue view 123
PRとIssueをつなぐ魔法の言葉 PRの説明文に Closes #123 や Fixes #123 と書いておくと、そのPRがマージされた瞬間にIssueが自動で閉じます 。単に #123 と書くだけでも相互にリンクが張られ、後から経緯をたどれるようになります。
3. コミットメッセージの規約
チームによっては、メッセージの形式が決まっています。世界的によく使われるのが Conventional Commits です。
Conventional Commits コピー
形式: 種類(範囲): 要約
feat(auth): パスワード再設定機能を追加
fix(login): エラーメッセージが表示されない不具合を修正
docs(readme): 環境構築手順を追記
style: インデントを整形(動作に影響なし)
refactor(order): 注文処理を関数に分割
perf(search): 検索クエリのN+1問題を解消
test(user): ユーザー登録のテストを追加
chore(deps): ライブラリを最新版に更新
ci: テスト実行のワークフローを追加
※ この形式にしておくと、リリースノートを自動生成できるという実利があります。ただし、絶対の正解ではありません。 日本語だけのチームなら「【修正】ログイン時のエラー表示」といった独自ルールでも構いません。大事なのはチーム内でそろっていること です。
4. レビューする側の作法
指摘の重みを言葉で分ける 「must:(直してください)」「should:(直したほうがよい)」「nits:(好みの範囲、直さなくてよい)」「imo:(個人的な意見)」「q:(質問)」のように接頭辞を付けると、受け取る側が優先順位を判断できます。すべての指摘を同じ強さで書くと、相手は何から直せばよいかわかりません。
5. 実務での1日の流れ
ある日のコマンド履歴(典型例) コピー
# --- 朝 ---
git switch main
git pull # 最新にする
git switch -c fix/456-login-error # 課題番号入りのブランチ
# --- 午前 ---
git status
git diff
git add src/auth.js
git commit -m "fix(login): 認証失敗時にエラーを返すよう修正"
# --- 昼過ぎ ---
git switch main && git pull # 他の人の変更を取り込む
git switch fix/456-login-error
git merge main # 自分のブランチを最新に追従させる
# --- 夕方 ---
git push -u origin fix/456-login-error
gh pr create --fill # PRを作成 → レビュー依頼
# --- 翌日、指摘を受けて ---
git add . && git commit -m "レビュー指摘: テストケースを追加"
git push # → 承認 → マージ → ブランチ削除
6. やってはいけないこと
練習問題
あなたのPRに、レビュアーから「この関数名は分かりにくいので変えてほしい」と指摘がありました。しかし、あなたには変える必要がないと思える理由があります。どう対応するのが適切ですか。
解答を見る
理由を書いて返信し、対話します。 黙って直すのも、黙って無視するのも不適切です。レビューは指示ではなく相談 だからです。「この名前は既存の UserService の命名に揃えています。全体を変えるなら別PRで行いたいですが、いかがでしょうか」のように、判断材料と代案を添えて返す のが実務的な対応です。
それでも意見が割れる場合は、PRのコメント上で延々と往復せず、10分話す ほうが早く解決します。そして決まったことは、必ずPRにコメントとして書き残してください。将来「なぜこの名前なのか」を調べる人のためになります。
このステップは理解できた
STEP 10
実務
現場でよく使う道具 ── stash・rebase・cherry-pick
目安 1〜2週間
このステップの到達点 ── 「作業を中断したい」「履歴を整理したい」「あのコミットだけ欲しい」といった現場で頻繁に起こる場面 に、適切なコマンドで対応できる。
1. git stash ── 作業を一時的に棚上げする
「まだコミットできる状態ではないが、急ぎで別の作業をしなければならない」という場面で使います。実務でいちばん出番の多い便利コマンド です。
ターミナル コピー
git stash push -m "検索機能 作りかけ" # 名前を付けて退避(推奨)
git stash # 名前なしでも可
git stash list # 棚上げしたものの一覧
git stash show -p stash@{0} # 中身を確認する
git stash pop # 最新のものを取り出して、棚からも消す
git stash apply stash@{1} # 指定のものを取り出す(棚には残す)
git stash drop stash@{0} # 棚から消す
git stash clear # 全部消す(要注意)
git stash -u # 新規作成した未追跡ファイルも退避する
git stash list の結果 stash@{0}: On feature/search: 検索機能 作りかけ
stash@{1}: WIP on main: c4d7e2b READMEに説明文を追加
stashの放置は事故のもと stashはブランチに紐づかないため、増えると「これは何の作業だったか」がわからなくなります。その日のうちに戻す のが原則です。長く保存したい作業は、stashではなく作業用ブランチにコミット してください。また、git stash は既定では未追跡ファイル(新規作成したファイル)を退避しません。-u を忘れると、新しく作ったファイルだけが取り残されます。
2. git rebase ── 履歴を一直線に整える
リベース は、自分のコミットを「相手の最新の上に、載せ直す」操作です。マージが「合流点を作る」のに対し、リベースは枝分かれ自体をなかったことにします 。
merge と rebase の違い コピー
【merge した場合】合流の記録が残る
A ── B ── C ──────── M (main)
└─ D ── E ────┘
【rebase した場合】自分のコミットが作り直されて一直線になる
A ── B ── C ── D' ── E' (feature)
▲
D と E は「別のコミット」として作り直される(ハッシュが変わる)
ターミナル コピー
git switch feature/search
git fetch origin
git rebase origin/main # main の最新の上に自分の作業を載せ直す
# コンフリクトが起きたら、1コミットずつ解決していく
git add 解決したファイル
git rebase --continue
git rebase --abort # やっぱりやめる
リベースの黄金律 「他人が持っている可能性のあるコミットは、絶対にリベースしない」 。リベースはコミットを作り直すため、共有済みの履歴に対して行うと、相手の履歴と食い違って大混乱になります。自分しか触っていない作業ブランチだけに使ってください。
3. git rebase -i ── コミットを整理してからレビューに出す
-i(対話モード)を使うと、自分のコミットをまとめたり、順番を変えたり、メッセージを直したり できます。「typo修正」「やっぱり戻す」といった恥ずかしいコミットを、レビュー前にきれいにできます。
ターミナル コピー
git rebase -i HEAD~4 # 直近4つのコミットを整理する
エディタで開かれる画面 コピー
pick 1a2b3c4 検索機能の骨組みを追加
squash 5d6e7f8 typo修正 ← 1つ上のコミットに吸収させる
squash 9a0b1c2 インデント修正 ← 同上
reword 3d4e5f6 検索結果の表示を追加 ← メッセージだけ書き直す
# 使える指示:
# pick = そのまま使う
# reword = 内容はそのまま、メッセージだけ変える
# edit = そこで一時停止して、内容を修正する
# squash = 1つ上のコミットに統合する(メッセージも統合)
# fixup = 1つ上に統合する(このコミットのメッセージは捨てる)
# drop = このコミットを削除する
# 上下の行を入れ替えると、コミットの順序も変わります
使うのはレビューに出す前だけ 実務では「作業中は雑にコミットしておき、PRを出す直前に rebase -i で整える」という使い方をします。ただし、Squash and merge を採用しているチームでは、そもそも不要 です(マージ時に自動で1つにまとまるため)。
4. git pull --rebase ── 履歴を汚さずに最新を取り込む
ふつうの git pull は、取り込むたびに「Merge branch 'main'...」という意味の薄いコミットを作ります。--rebase を付けると、それを作らずに済みます。
ターミナル コピー
git pull --rebase
# 毎回この動きにしたい場合(多くの現場でおすすめ)
git config --global pull.rebase true
5. git cherry-pick ── 特定のコミットだけを取り込む
「開発ブランチで直した不具合修正だけを、緊急で本番ブランチにも入れたい」という場面で使います。
ターミナル コピー
git switch main
git cherry-pick 7a2b9c1 # そのコミットの変更内容だけを持ってくる
git cherry-pick 7a2b9c1 3f8d2e5 # 複数まとめて
git cherry-pick a1b2c3d..e4f5g6h # 範囲で指定
多用するのは危険信号 cherry-pickは同じ変更を複数の場所に複製するため、乱用するとどこに何が入っているのかわからなくなります 。「緊急時の例外的な手段」と考え、通常はブランチとマージで整理してください。
6. git tag ── リリースに印を付ける
ターミナル コピー
git tag v1.0.0 # 軽量タグ
git tag -a v1.0.0 -m "初回リリース" # 注釈付きタグ(実務ではこちら)
git tag # 一覧
git show v1.0.0 # 中身を確認
git push origin v1.0.0 # タグをリモートに送る
git push --tags # すべてのタグを送る
git tag -d v1.0.0 # 手元のタグを削除
※ 版番号は セマンティックバージョニング(v メジャー.マイナー.パッチ) が世界標準です。メジャー =互換性のない変更、マイナー =後方互換のある機能追加、パッチ =不具合修正。v1.4.2 なら「1系の4回目の機能追加の、2回目の修正」という意味になります。
7. git bisect ── 不具合が入った地点を二分探索で特定する
「1か月前は動いていたのに、いつの間にか壊れている」というときに使います。Gitが自動で二分探索 してくれるので、100個のコミットでも7回程度の確認で原因にたどり着けます。
ターミナル コピー
git bisect start
git bisect bad # 今は壊れている
git bisect good v1.2.0 # このときは動いていた
# → Gitが中間のコミットに移動する。動作を確認して…
git bisect good # 動いた場合
git bisect bad # 壊れていた場合
# → これをくり返すと、原因のコミットが特定される
git bisect reset # 終了して元のブランチに戻る
特定できたときの表示 b7f3a92c1d4e5a6b7c8d9e0f1a2b3c4d5e6f7a8b is the first bad commit
検索処理のキャッシュを追加
8. その他、知っておくと助かるもの
ターミナル コピー
git clean -n # 未追跡ファイルの削除対象を「確認だけ」する
git clean -fd # 未追跡のファイルとフォルダを削除(要注意)
git restore --source=HEAD~3 app.js # 3つ前の状態のファイルだけを取り戻す
git worktree add ../hotfix main # 同じリポジトリを別フォルダにも展開する
# (ブランチを切り替えずに2つ同時に作業できる)
git shortlog -sn # 誰が何コミットしたかの集計
git log --since="1 month ago" --oneline | wc -l # 直近1か月のコミット数
git config --global alias.st status # 短縮名を作る
git config --global alias.lg "log --oneline --graph --all"
# → 以後 git st / git lg で使える
練習問題
PRを出す直前に履歴を見ると、「実装」「typo」「typo2」「レビュー準備」という4つのコミットが並んでいました。これを1つのきれいなコミットにまとめる手順を書いてください。
解答を見る
ターミナル コピー
# 方法A: 対話的リベースでまとめる
git rebase -i HEAD~4
# エディタで、2〜4行目の pick を squash(または fixup)に書き換えて保存
# → 統合後のメッセージを整えて保存
# 方法B: reset --soft を使う(こちらのほうが簡単)
git reset --soft HEAD~4
git commit -m "feat(search): ユーザー名での絞り込み機能を追加"
# すでに push 済みのブランチなら、書き換えた履歴を送り直す必要がある
git push --force-with-lease
※ --force-with-lease は「自分が最後に確認した状態からリモートが変わっていなければ上書きする」という安全版の強制pushです。誰も触っていない自分専用のブランチに限って 使ってください。--force は使わないこと。
このステップは理解できた
STEP 11
実務
GitHub Actions ── 自動でテストする仕組みを作る
目安 1〜2週間
このステップの到達点 ── PRを出すと自動でテストが走る仕組みを、自分で作れる。「壊れたコードはマージできない」状態を作れると、チームの安心感が根本から変わります。
CI/CDとは
CI(継続的インテグレーション) とは、コードを push するたびに自動でテストや点検を実行する 仕組みのことです。CD(継続的デリバリー/デプロイ) は、そこからさらに自動で公開まで行うことを指します。
人間は「確認し忘れ」を必ずします。機械は忘れません。レビューで人間が見るべきなのは設計や意図であって、「テストを通したか」の確認ではありません。
1. 置き場所とファイル形式
リポジトリの .github/workflows/ フォルダに、.yml ファイルを置くだけで動きます。サーバーの用意は不要で、無料枠の範囲内なら費用もかかりません(パブリックリポジトリは基本無料)。
.github/workflows/ci.yml コピー
name: CI
# いつ動かすか
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest # どんな環境で動かすか
steps:
- name: リポジトリを取得する
uses: actions/checkout@v4
- name: Python を用意する
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: ライブラリを入れる
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: 書き方を点検する
run: ruff check .
- name: テストを実行する
run: pytest -v
PR画面での表示 ✓ CI / test (pull_request) Successful in 42s
→ 「All checks have passed」と表示され、マージボタンが緑になる
✗ CI / test (pull_request) Failing after 38s
→ 「Some checks were not successful」 マージ前に直す必要がある
2. YAMLの読み方
YAMLはインデントが命 半角スペースの数で階層を表します。タブ文字は使えません 。ずれるとエラーになり、しかも原因がわかりにくいので、エディタの設定で「タブをスペースに変換」を有効にしておいてください。
3. Node.js の場合
.github/workflows/node-ci.yml コピー
name: Node CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20, 22] # 2つの版で同時に検証する
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "npm" # 依存パッケージを再利用して高速化
- run: npm ci # package-lock.json に忠実に入れる
- run: npm run lint
- run: npm test
4. 秘密情報の渡し方(Secrets)
APIキーなどをYAMLに直接書いてはいけません。GitHubの Settings → Secrets and variables → Actions に登録し、名前で参照します。
.github/workflows/deploy.yml(一部) コピー
- name: デプロイする
env:
API_KEY: ${{ secrets.API_KEY }}
SLACK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
run: ./scripts/deploy.sh
※ Secretsに登録した値は、実行ログでも *** と伏せて表示されます。ただし自分でわざと表示するコードを書けば漏れます 。また、フォークからのPRでは既定でSecretsが渡されません(悪意ある人が盗み出すのを防ぐため)。
5. よく使う自動化の例
6. GitHub Pages で公開する
HTMLを置いたリポジトリなら、無料でWebサイトとして公開できます。Settings → Pages で公開元のブランチを選ぶだけです。
公開されるURL コピー
https://ユーザー名.github.io/リポジトリ名/
# ユーザー名.github.io という名前のリポジトリなら
https://ユーザー名.github.io/
7. READMEにバッジを付ける
README.md コピー

※ テストが通っていれば緑、失敗していれば赤で表示されます。「このリポジトリはちゃんと動いている」という信頼の証 になるので、公開リポジトリにはぜひ付けてください。
練習問題
「PRを出したときだけ、Python 3.11と3.12の両方でテストを実行する」ワークフローを書いてください。
解答を見る
.github/workflows/pr-test.yml コピー
name: PR Test
on:
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- run: pip install -r requirements.txt
- run: pytest -v
※ matrix を使うと、指定した組み合わせの数だけジョブが並行して動きます。版の違いによる不具合を早期に見つけられる、実務でよく使う書き方です。
このステップは理解できた
STEP 12
実務
リポジトリの運用設定 ── 事故が起きない仕組みを作る
目安 1週間
このステップの到達点 ── ブランチ保護、テンプレート、自動更新などを設定し、「気をつける」ではなく「仕組みで防ぐ」 状態を作れる。ここができると、チームを任される側に回れます。
1. ブランチ保護 ── mainを守る
最も重要な設定です。Settings → Branches(または Rules → Rulesets) から、mainブランチに対して次のような制約をかけられます。
ひとりで開発している場合でも設定する価値があります 「自分だけだから大丈夫」と思っていても、深夜の作業でうっかりmainに直接pushする事故は起こります。ルールは、疲れているときの自分を守るためのもの です。
2. テンプレートを用意する
PRやIssueの書き方を毎回思い出すのは大変です。雛形をリポジトリに置いておけば、自動的に入力欄に反映されます。
.github/pull_request_template.md コピー
## 概要
<!-- 何をしたか、1〜2行で -->
## 背景・目的
<!-- なぜこの変更が必要か。関連するIssue: # -->
## 変更点
-
-
## 動作確認
- [ ] ローカルで動作確認した
- [ ] テストを追加/更新した
- [ ] 既存の機能を壊していないことを確認した
## レビューで見てほしい点
.github/ISSUE_TEMPLATE/bug_report.md コピー
---
name: 不具合の報告
about: 動作がおかしいときはこちら
labels: bug
---
## 起きていること
## 再現手順
1.
2.
## 期待する動作
## 環境
- OS:
- ブラウザ:
3. CODEOWNERS ── 自動でレビュー担当を割り当てる
.github/CODEOWNERS コピー
# 既定のレビュー担当
* @team-lead
# 特定のフォルダごとに担当を分ける
/src/frontend/ @frontend-team
/src/api/ @backend-team
/infra/ @sre-team
/docs/ @tech-writer
# 特に重要なファイルは複数人で見る
/src/auth/ @security-team @team-lead
※ 該当するファイルが変更されたPRには、自動でレビュー依頼が飛びます 。ブランチ保護の「Require review from Code Owners」と組み合わせると、担当者の承認なしにはマージできなくなります。
4. Dependabot ── ライブラリの更新を自動化する
使っているライブラリに脆弱性が見つかったとき、自動で更新PRを作ってくれる 仕組みです。セキュリティ対応の抜け漏れが確実に減ります。
.github/dependabot.yml コピー
version: 2
updates:
- package-ecosystem: "pip" # npm / pip / gradle / composer など
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
更新PRは溜めないこと 週に1度、まとめて確認する時間を決めておくのがコツです。放置すると数十件のPRが溜まり、結局誰も見なくなります。CIが通っている小さな更新PRは、その場でマージしてしまってかまいません。
5. リリースを作る
ターミナル(GitHub CLI) コピー
git tag -a v1.2.0 -m "検索機能を追加"
git push origin v1.2.0
gh release create v1.2.0 --generate-notes # 変更点を自動でまとめてくれる
gh release list
※ --generate-notes を付けると、前回のリリース以降のPRのタイトルから、リリースノートが自動生成されます。PRのタイトルを丁寧に書く理由は、ここにもあります。
6. その他、入れておくとよいファイル
.gitattributes(改行コード事故の予防) コピー
# 全テキストファイルの改行を統一する
* text=auto eol=lf
# シェルスクリプトは必ずLF
*.sh text eol=lf
# バッチファイルは必ずCRLF
*.bat text eol=crlf
# バイナリとして扱う(差分を出さない)
*.png binary
*.xlsx binary
練習問題
「テストが失敗しているのに、急いでいるメンバーがmainにマージしてしまった」という事故が起きました。次から防ぐには、どの設定を入れますか。
解答を見る
ブランチ保護で、次の3つを組み合わせます。
Require status checks to pass before merging ── CIが成功していないとマージボタンが押せなくなる
Require a pull request before merging(承認1名以上) ── 単独でmainを触れなくする
Do not allow bypassing the above settings ── 管理者権限でも例外にしない
※ 「次から気をつけましょう」は対策ではありません。人の注意力に頼る運用は、必ずいつか破られます。 仕組みで防げるものは、仕組みで防いでください。
このステップは理解できた
STEP 13
実務
事故対応と、その先へ
目安 1週間
このステップの到達点 ── 実際に起きる事故に、慌てずに対処できる。Gitで本当に困るのは、コマンドを知らないときではなく、慌てて余計な操作を重ねたときです。
1. 困ったときの対処表
2. detached HEAD(切り離されたHEAD)
初学者を最も驚かせる表示です。git checkout ハッシュ などでブランチではなく特定のコミットに直接移動した状態 を指します。壊れているわけではありません。
表示 You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
ターミナル コピー
git switch main # 元に戻る(ここでのコミットは捨てられる)
git switch -c experiment # ここでの作業をブランチとして残す
3. 秘密情報をコミットしてしまった
これは技術の問題ではなく、セキュリティ事故です。 対応の順番を間違えないでください。
対応の順番 コピー
① 何よりも先に、その鍵・パスワードを無効化して作り直す(ローテーション)
← 履歴から消すより、こちらが先。すでに見られている前提で動く
② 会社のルールに従って報告する(隠さない)
③ .gitignore に追加し、以後同じことが起きないようにする
④ そのうえで、履歴からの削除を検討する
ターミナル(履歴から消す場合) コピー
# まだ push していない直前のコミットなら、これで済む
git rm --cached .env
git commit --amend --no-edit
# すでに push 済みで、過去の履歴から完全に消したい場合
# (専用ツール git-filter-repo を使う。全履歴が書き換わる大手術)
pip install git-filter-repo
git filter-repo --path .env --invert-paths
git push --force --all
履歴の書き換えは全員に影響します filter-repo は全コミットのハッシュを変えるため、そのリポジトリを持っている全員が clone し直す必要があります。必ずチームに周知してから、責任者の判断のもとで実施してください。 そして、これを行ってもすでに流出したキーが安全になるわけではありません 。①のローテーションが最優先である理由です。
4. 巨大なファイルを入れてしまった
GitHubには1ファイル100MBの上限があり、超えるとpushが拒否されます。また、リポジトリが大きくなるとcloneが極端に遅くなります。
ターミナル コピー
# 大きなファイルを扱う専用の仕組み(Git LFS)
git lfs install
git lfs track "*.psd"
git lfs track "*.mp4"
git add .gitattributes
そもそも入れない判断も大事です 動画・大量の画像・データセットなどは、Gitではなくクラウドストレージに置き、リポジトリにはその場所へのリンクだけを書く ほうが健全なことが多いです。Gitはテキストの履歴管理に最適化された道具 で、バイナリの管理は本来得意ではありません。
5. アンチパターン集
6. GUIツールを使ってよいのか
結論から言えば、使ってかまいません 。実務でも、差分の確認やコンフリクト解決は画面で行うほうが速く、正確です。
ただし、コマンドで何が起きているかを理解したうえで使ってください 。GUIのボタン1つが、裏側で fetch+merge+push を実行していることがあります。仕組みを知らないままボタンを押すと、事故が起きたときに何が起きたのか説明できません。
7. この先に学ぶこと
実際のチーム開発 ── 何より効きます。オープンソースへの小さなPRでも、確実に経験になります
CI/CDの本格運用 ── テスト・ビルド・デプロイの自動化(STEP 11の続き)
コンテナとGit ── Dockerfileをリポジトリに入れ、環境ごと再現できるようにする
モノレポ運用 ── 複数のプロジェクトを1つのリポジトリで管理する方法
コードレビューの技術 ── 指摘の質は、経験とともに上がります
Gitの内部構造 ── オブジェクト(blob / tree / commit)の仕組みを知ると、すべてが腑に落ちます
最後に、いちばん大事なこと Gitは「失敗しても戻れる」ための道具 です。こわがって使わないのが、いちばんもったいない使い方になります。練習用リポジトリを1つ作って、そこで思いきり壊してみてください。reflogがあるかぎり、コミットさえしていれば、たいていのことは元に戻せます。
練習問題
朝、git status を打ったら「HEAD detached at 8f2a91c」と表示され、昨日書いたはずのコードが見当たりません。どういう状態で、どう対処しますか。
解答を見る
ブランチではなく特定のコミットに直接移動している状態です。昨日の作業は消えたのではなく、別のコミット(またはブランチ)の側にあります 。
ターミナル コピー
git status # まず状態を確認する
git reflog # HEADがどう動いたかの記録を見る
git branch -a # ブランチの一覧を確認
# ① この状態で作業してしまっていた場合 → ブランチとして保存する
git switch -c rescue-work
# ② 何もしていない場合 → 元のブランチに戻るだけでよい
git switch main
git log --oneline # 昨日のコミットがあるか確認
※ ここで慌てて git reset --hard を打つのが最悪の一手です。まず現状を確認する 。この順番さえ守れば、Gitで取り返しのつかない事態になることはほとんどありません。
このステップは理解できた