エンジニア1年目としてチーム開発に参加してから、Gitで何度も詰みそうになりました。
この記事はそんな自分の備忘録兼、未来の誰かの助けになればと願って書いたものです。
対象:チーム開発を始めたばかりのエンジニア
目的:実践的なGitの使い方を“ケース別”に理解する
🗂 目次(ケース別Gitトラブル対応集)
- 🧩 ケース1:作業中にmainが更新されていた!
- 🧩 ケース2:一部のコミットだけを他ブランチに持っていきたい!
- 🧩 ケース3:間違えてmainにコミットしちゃった!
- 🧩 ケース4:作業途中だけど、別のタスクを急に振られた!
- 🧩 ケース5:コミット履歴をきれいにしたい
- 🧩 ケース6:本番環境でバグ発生!「あの1コミットだけ消したい」
- 🧩 ケース7:今どのブランチで何が起きてるのか混乱!
🧩ケース1:作業中にmainが更新されていた!
💡 よくある状況
-
mainからfeature/loginブランチを切って作業していた - 自分が作業している間に、他の人が
mainに変更をマージしていた - そのまま自分のブランチをマージしようとすると、競合や不整合の原因に!
🧠 基本の流れ(どのブランチで何をする?)
今いる作業ブランチ(例:`feature/login`)を最新の `main` に追いつかせる
↓
そのために「最新の `main` の状態」を取得する必要がある
↓
→ それが **`git fetch`**
🔍 git fetch とは?
- 「リモートの最新の状態を ローカルに取得する」コマンド
- 実行しても、自分の作業コードには一切影響なし
たとえば、GitHub上のmainが更新されていても、git fetchしないとローカルでは気づけません。
✅ どのブランチで fetch するの?
-
git fetchは どのブランチにいても実行可能 - 「取得するだけ」なので、安全にいつでも実行OK
ただし、rebase や merge を行うときは、自分の作業ブランチに切り替えてから行う必要があります。
🔄 最新の main に追いつく手順
-
自分の作業ブランチにいることを確認
(例:feature/login) -
git fetch originでリモートの最新状態を取得する
(まだローカルのmainには反映されない) -
git rebase origin/mainで、最新のmainに履歴を並び替える
🧯 コンフリクトが出たら?
- コンフリクトしたファイルをエディタで修正
- 修正したファイルを
git add -
git rebase --continueでリベース再開
もし途中で「あ、無理だな」となったら
→ git rebase --abort で中止できます。
✅ merge と rebase の違い
| 操作 | 役割 | 履歴の見え方 |
|---|---|---|
merge |
ブランチを合流させる | 分岐→合流点ができる |
rebase |
履歴を1本に並び替えて整える | きれいな一直線になる |
🧠 コマンド例(ブランチ名付き)
作業ブランチ feature/login にいる状態で:
-
git fetch origin
→ 最新のorigin/mainを取得 -
git rebase origin/main
→ 最新mainに追いつくよう履歴を整える
🪄 履歴のイメージ(テキスト図)
① git fetch の前
#(リモート)
origin/main --- A --- B
#(ローカル)
main --- A ← ※まだBを知らない!
↑
fetch前の状態
feature/login --- X --- Y
- 自分のローカル環境では main はコミットAまでしか持っていません。
- 他の人が main にBを追加していても、fetchするまではローカルには伝わりません。
- 一方、feature/login ブランチではあなたがX→Yという作業を進めています。
② git fetch 実行後
(リモート)
origin/main --- A --- B
(ローカル)
main --- A ← ※まだ更新されていない
origin/main --- A --- B ← ← ← ← これがfetchの結果
(取得して“見えるようになった”)
feature/login --- X --- Y
- git fetch origin によって、origin/main に最新のBまでの情報が届きます。
- ですがまだローカルの main は古いまま。自分のコードにも影響はなし。
③ git rebase origin/main 実行後
#(ローカルブランチ構成)
origin/main --- A --- B
\
feature/login X' --- Y'
- rebase は、XとYの変更を、Bのあとに並び替えて再適用する操作。
- 元のXとYは削除され、新しく X'・Y' というコミットに生まれ変わります。
- 履歴が 一本の線として整い、後から見たときに非常に分かりやすくなるのが最大の利点。
☝️ 注意点:rebaseの副作用
- rebase は 履歴を書き換えるため、すでにpush済みのブランチに使うと注意が必要!
- チームによっては「push前のローカル作業だけrebase可」とルール化されていることも。
📌 ワンポイントTips
# fetchしてリモートの状態だけ確認したい
git fetch origin
git log origin/main --oneline
# rebase前にコミット差分を確認したい
git log origin/main..HEAD --oneline
🧩ケース2:一部のコミットだけを他ブランチに持っていきたい!
💡 よくある状況
- 複数の機能を同じブランチでまとめて開発していた
- でも「この1つの修正だけを別のブランチに持っていきたい!」という場面
- バグ対応を先にリリースブランチに入れたい
- 本当は分けるべきだったけど、まとめてコミットしちゃった…
🧠 こういうときに使えるのが git cherry-pick
🍒 cherry-pickとは?
- 指定した1つのコミットだけを、他のブランチに適用するコマンドです。
- 名前の通り「コミットを摘み取って持ってくる」イメージです。
✅ 基本的な使い方
手順:
- 1、対象のコミットIDを調べる(git logなど)
- 2、持っていきたいブランチに移動
- 3、git cherry-pick <コミットID> を実行!
🌱 例:featureブランチ → hotfixブランチに1コミットだけ移したい
# 今は feature/awesome にいるとする
git log --oneline
# → 例えば以下のような履歴が表示される
# a1b2c3d 修正1(これは不要)
# e4f5g6h 修正2(←これだけhotfixに入れたい)
# 1. hotfixブランチに移動
git checkout hotfix/login-bug
# 2. 特定のコミットを摘み取る
git cherry-pick e4f5g6h
🔁 cherry-pick のよくある使い方パターン
| シーン | 内容 | 効果 |
|---|---|---|
| リリースブランチへの適用 | 特定の修正だけ先に入れたい | 緊急バグ対応で便利 |
| 作業を間違ったブランチでしてた | 必要なコミットだけ移す | resetしてやり直すより安全 |
| コードレビュー前に分離したい | 一部コミットだけ分ける | 複数PRに切り出せる |
🧯 cherry-pick 時にコンフリクトが出たら?
cherry-pick も「1コミット分の rebase」のような動作をするので、元のブランチと差分があると衝突します。
# 衝突したファイルを修正
git add <修正済みファイル>
# cherry-pick 再開
git cherry-pick --continue
# どうしても無理なら
git cherry-pick --abort
🧠 cherry-pick のイメージ図(テキスト図)
#(元の履歴)
feature/awesome:
A -- B -- [ C ] -- D -- E
↑
このコミットだけ欲しい!
hotfix/login-bug:
H -- I
# cherry-pick 後:
hotfix/login-bug:
H -- I -- [ C' ]
- [C] の内容が [C'] としてコピーされる
- コミットIDは変わるが、中身は同じ
🎯 一言まとめ
この1コミットだけほしいは、迷わず cherry-pick!
ブランチ運用を柔軟にしてくれる、めちゃ便利なコマンドです。
🧩ケース3:間違えてmainにコミットしちゃった!
💡よくある状況
- main にいることに気づかず、ついそのまま作業&コミットしてしまった…
- プルリクを出すつもりが、mainブランチが汚れてしまった!
- 「開発用ブランチ切るの忘れてた!」
✅ 状況別の対処法を紹介!
✔️ パターンA:まだ push していない(ローカルだけ)
これは一番安全に修正できる状態です!
→ git reset で履歴を戻そう!
🔧 直前のコミットを取り消す(作業は残す)
git reset --soft HEAD^
- コミットだけ消す
- ステージング(add済み)は維持される
🧹 直前のコミット+add も取り消す(作業ファイルは残す)
git reset --mixed HEAD^
-
git add前の状態に戻る - 編集内容は残っている
🔥 完全に削除したい(作業内容ごと取り消し)
git reset --hard HEAD^
- 完全に1コミット前に戻す(※元に戻せないので注意!)
💡 HEAD^ って?
-
HEAD:今いるブランチの最新コミット -
HEAD^:その1つ前(1個前の履歴) -
HEAD~2:2つ前 という意味
✔️ パターンB:もう push してしまった!
この場合は、無理に履歴を書き換えると他の人に影響が出ます。
→ 基本的には revert で「打ち消しコミット」を作るのが安全です!
🪃 git revert を使う
git revert <コミットID>
- そのコミットの変更を「打ち消す」新しいコミットを作る
- 既に共有された
mainに対しても安全に使える
🧠 reset と revert の違いは?
| コマンド | 目的 | 履歴への影響 | チーム開発での安全性 |
|---|---|---|---|
reset |
履歴を巻き戻す | 元のコミットごと削除 | ❌ push済みだと危険 |
revert |
履歴を残したまま取り消す | 「打ち消し」の新コミットが追加される | ✅ 安全! |
🧪 イメージ図:revertの動作
# mainブランチの履歴:
A --- B --- C
↑
間違えた!
# revertすると:
A --- B --- C --- C'(Cを打ち消すコミット)
🧩ケース4:作業途中だけど、別のタスクを急に振られた!
💡 よくある状況
- 作業ブランチでコードを編集中。まだコミットしていない状態。
- そこに突然「バグ対応お願い!」と別タスクが…
- でもこのままブランチを切り替えると、作業中のファイルが残ってて checkout できない!
🧠 こういうときに使うのが git stash
💬 stasとは?
今の作業内容を一時的に保存して“棚にしまう”ことができるコマンド。
- 作業内容(ステージング済み/未済みの変更)を“スッ”と退避できる。
- あとで簡単に取り出して再開できる。
✅ 基本の使い方
git stash
- これだけで 作業中の変更がまっさらに!
- 編集中だったファイルが元に戻って、ブランチ切り替えが可能に。
🔁 作業を戻すとき(stashの取り出し)
git stash apply
- 棚から内容を適用する(でも stash はそのまま残る)
git stash pop
- 棚から取り出して適用&削除する(取り出しながら片付け)
| コマンド | 何をする? | stashの中身は? |
|---|---|---|
git stash apply |
保存しておいた作業内容を復元する | 残る(また使える) |
git stash pop |
作業内容を復元して削除する | 消える(1回限り) |
🧠 stash のイメージ図(テキスト)
#(作業中)
feature/login:
- app.js(編集中)
- styles.css(未add)
↓ git stash で保存
#[作業状態が一時的に空になる]
↓ hotfixブランチでバグ修正
↓ feature/login に戻って git stash pop
編集内容がそのまま戻ってくる!
✅まとめ
| コマンド | 目的 | 補足 |
|---|---|---|
git stash |
作業を一時退避 | 途中で作業切り替えたいとき |
git stash pop |
退避内容を戻して削除 | 元に戻して作業再開 |
git stash apply |
戻すだけ(削除はしない) | 繰り返し使いたい場合に便利 |
git stash list |
stash一覧を確認 | 最新は stash@{0}
|
git stash clear |
すべて削除 | 後腐れなくしたい時に |
🧩ケース5:コミット履歴をきれいにしたい
💡 よくある状況
- 「小さな修正で何回もコミットしちゃった...」
- 「あとから見返すと fix typo 調整 微調整2 とかばっかでダサい...」
- 「レビューする人にも見づらい履歴になっちゃった...」
🧠 こういうときの味方が git rebase -i
📘 rebase -i(インタラクティブ・リベース)とは?
複数の直近コミットをまとめたり、編集したり、削除したりできるツール
- 履歴を「あとから編集」する感覚
- コミット単位で整えられるので、レビューしやすく・理解しやすい履歴が作れる
✅ 使い方:基本の流れ
🔧 1. 直近のコミットを編集モードで開く
たとえば「直近3件のコミットをまとめたい」なら:
git rebase -i HEAD~3
-
HEAD~3は「今の位置から3つ前まで」という意味 - 実行すると、エディタが開いて以下のような画面に👇
pick a1b2c3 初回コミット
pick d4e5f6 スタイル微調整
pick 789abc コンポーネント追加
✍️ 2. コマンドを変更して操作する
| コマンド | 意味 | 使い道 |
|---|---|---|
pick |
そのまま使う | 変更なし |
reword |
メッセージだけ変更 | 誤字や曖昧な表現を直す |
squash |
前のコミットにまとめる(履歴も結合) | 小さな修正をまとめたいとき |
fixup |
前のコミットにまとめる(メッセージは残さない) | typoとかの修正に最適 |
drop |
削除する | 不要なコミットを消す |
✅ 例:2つのコミットを1つにまとめて、メッセージも整える
pick a1b2c3 初回コミット
squash d4e5f6 スタイル微調整
すると、次に新しいコミットメッセージを書く画面が出てきます。
# コミットメッセージを編集してください
初回コミット + スタイル微調整
ここで統合された履歴として保存できます。
🧪 使う前後の履歴の違い(テキスト図)
📦 Before
A --- B --- C --- D
↑
fix typo
🧼 After(BとCをまとめた)
A --------- B'
\
D
- BとCがまとめられ、履歴がすっきり
- B'として新しいコミットになっている(IDは変わる)
🧩ケース6:本番環境でバグ発生!「あの1コミットだけ消したい」
💡 よくある状況
- 本番にマージされた後で「やばい!この1コミットが原因でバグ出てる!」
- けど
mainにそのままコミットされちゃったし、履歴を壊すわけにはいかない…! -
resetで戻すと他の人のリポジトリも壊れるかも…!?
🧠 こういうとき使うのが git revert
🔄 指定したコミットを“打ち消す”新しいコミットを追加するのが revert
- 履歴を壊さず、安全に修正を巻き戻せる
- push済みのmainブランチに対しても安心して使える
✅ 基本の使い方
git revert <コミットID>
- 指定したコミットと逆の操作を行うコミットを新たに追加する
-
resetと違って履歴を消さないので、共有ブランチでも安全
🧪 イメージ図:revert の仕組み
元の履歴:
A --- B --- C ← これがバグの原因!
revert C をすると…
A --- B --- C --- C'(Cを打ち消すコミット)
✅ 複数のコミットを一気に戻したい場合
git revert <コミットID1> <コミットID2> <コミットID3>
⚠️ reset との違いは?
| コマンド | 何をする? | 履歴への影響 | 本番向き? |
|---|---|---|---|
reset |
履歴を巻き戻す | 履歴が上書きされる | ❌ NG(push後に使うと危険) |
revert |
指定した変更を打ち消す | 履歴はそのまま残る | ✅ OK(チーム開発・本番で安全) |
🎯 一言まとめ
本番で「やばい1コミット」が混入したら、冷静に git revert!
チームの履歴を壊さず、安全に対応できるプロの選択です 💪
🧩ケース7:今どのブランチで何が起きてるのか混乱!
💡 よくある状況
- マージ・リベース・cherry-pick いろいろやってたら…
- 「あれ、今自分どのブランチにいるんだっけ?」
- 「このコミットってどこから来たんだ?」
- 「pushしたの?してないの?」
Git初心者〜中級者が誰でも一度は通る履歴迷子の瞬間です。
✅ 1. 今どのブランチにいるか?(基本)
git branch
- ※ が付いているのが現在のブランチ
- 安全に確認できる最初の一歩
✅ 2. 履歴を構造で見たい → git log --oneline --graph
git log --oneline --graph --all
- ブランチの分岐やマージの流れを視覚的に表示
- --all を付けることで、すべてのブランチの履歴が見える!
* f3c5d12 (HEAD -> feature/login) Fix login bug
| * a9b7e55 (origin/main) Add footer
|/
* 8a9b5c4 Initial commit
コミット構造(テキストで展開)
コミットID ブランチ 内容
--------------------------------------------------------
f3c5d12 ← HEAD & feature/login Fix login bug
a9b7e55 ← origin/main Add footer
8a9b5c4 Initial commit
-
HEAD ->
feature/login
→ 今作業しているのはfeature/loginブランチ。
→ その最新コミットが f3c5d12(ログインバグ修正) -
origin/main
→ リモートの main ブランチは a9b7e55 の時点で止まっている -
|/ という線
→feature/loginとorigin/mainがそれぞれInitial commit(共通の祖先)から分岐していることを示す
✅ 3. 「何やったか全然覚えてない」→ git reflog
git reflog
- 「自分がGitに何を指示したか」の履歴
-
commit,checkout,merge,rebase,resetなど、すべての操作履歴が見える!
例:
abc1234 HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/foo
def4567 HEAD@{1}: checkout: moving from main to feature/foo
- これがあれば「どこまで戻せばよかったんだっけ?」がわかる!
✅ 4. 現在の HEAD がどこを指してるのか確認 → git rev-parse --abbrev-ref
git rev-parse --abbrev-ref HEAD
現在の HEAD(=自分が見てる地点)のブランチ名をピンポイントで確認できる
🧠 こうやって使い分けよう!
| 知りたいこと | コマンド | 用途 |
|---|---|---|
| 自分のいるブランチ |
git branch / git rev-parse
|
今どこ? |
| 全体の履歴構造 | git log --oneline --graph --all |
分岐・マージの流れ |
| 何をやってきたか | git reflog |
過去の自分の操作 |
| pushしてる?未push? | git status |
状況チェック |
🎯 一言まとめ
迷子になったら reflog と graph!
Gitの履歴は“見える化”してナンボです。慌てず、冷静に状況把握を!
これで全7ケース、リアルなチーム開発でよくあるGitハプニング集が出揃いました!
「Git大辞典」としてまとめてきましたが、そもそもこうした操作が活きるのは、日頃からこまめにコミットしているからこそです。
誰が見てもわかりやすく、保守・運用しやすい履歴を残すためにも、
読みやすいコミット、粒度の細かいコミットを意識しておきたいですね。