「git reset --hardしたら数時間分の作業がまるごと消えた」「git push --forceしたらチームメンバーのコミットまで巻き添えで消えた」—— Gitを使っていると一度は経験する、あるいは聞いたことがあるヒヤリハットです。 Gitのコマンドは似た名前・似た機能のものが多く、「変更を取り消したい」という同じ目的でもreset・revert・restoreのどれを使うべきか迷いがちです。この記事では「やりたいこと」を起点に、 安全なコマンドと危険なコマンドを整理して逆引きできるようにまとめました。
1. 「やりたいこと」から探すGitコマンド一覧
Gitコマンドを覚えるコツは、コマンド名を暗記するのではなく「やりたいこと」から逆引きすることです。まずは代表的な操作を目的別に整理します。
| やりたいこと | コマンド例 | 安全度 |
|---|---|---|
| 直前のコミットをやり直す前の変更確認 | git diff --staged | 安全 |
| ステージした変更を取り消したい | git restore --staged | 安全 |
| 作業ディレクトリの変更を破棄したい | git restore | 危険 |
| 公開済みのコミットを打ち消したい | git revert | 安全 |
| コミット履歴ごと過去に巻き戻したい | git reset --hard | 危険 |
| 作業を一時的に退避したい | git stash | 安全 |
| ブランチを新しく作って移動したい | git switch -c | 安全 |
| 履歴を書き換えてリモートに反映したい | git push --force-with-lease | 危険 |
| 消してしまった変更を探したい | git reflog | 安全 |
より多くのコマンドを「やりたいこと」から探したい場合は、Gitコマンド逆引き検索で目的やキーワードを入力すると、コマンド・構文・実行例・安全度がまとめて表示されます。
2. 破壊的操作と安全な操作の見分け方
Gitのコマンドには「間違えても後から取り消せる安全な操作」と 「実行した時点で元のデータが失われる破壊的操作」の2種類があります。 この2つを区別できているかどうかが、事故を防げるかどうかの分かれ目です。
| 操作 | 危険な版 | 安全な代替 | 違い |
|---|---|---|---|
| コミットの取り消し | git reset --hard | git revert | resetは履歴を消す。revertは打ち消しコミットを積む |
| リモートへの反映 | git push --force | git push --force-with-lease | --forceは無条件上書き。--force-with-leaseは他人の変更を検知して失敗する |
| 変更の破棄 | git checkout . | git restore . | checkoutは多機能で誤用しやすい。restoreはファイル復元専用 |
| 未追跡ファイルの削除 | git clean -fd | git clean -n(確認のみ) | -fdは即削除。-nはドライラン(実際には削除しない)で対象を確認できる |
共通する考え方は「すでに公開済みの履歴を直接書き換えるコマンドは危険」ということです。 自分だけのローカルブランチであれば多少荒っぽく操作しても問題ありません。 ただしdevelop・mainのような共有ブランチや、他のメンバーがpullしているブランチでは、 履歴を書き換えるコマンド(reset --hard・force push・rebase後のforce push)は避けるべきです。 共有ブランチではrevertのように履歴を積み増す方式を選ぶのが安全です。
3. 「やらかした後」のリカバリ知識
どれだけ気をつけていても、事故はゼロにはできません。大事なのは 「やらかした後にどう復旧するか」を知っておくことです。
git reflog でHEADの移動履歴を追う
git reflogは、HEAD(今いる場所)がこれまでどう移動してきたかの記録です。git reset --hardで巻き戻した場合でも、巻き戻す前のコミットハッシュがreflogに残っていることが多く、 以下の手順で復元を試せます。
# 1. HEADの移動履歴を確認する git reflog # 2. 消える前のコミットハッシュ(例: a1b2c3d)を見つけて戻す git reset --hard a1b2c3d
ただしreflogに記録が残るのは「一度でもコミットしたことがある変更」に限られます。git addすらしていない編集中のファイルは復元できないため、作業中はこまめにgit commitするかgit stashで退避しておくことが最大の保険になります。
force push でリモートを壊してしまったら
自分がforce pushで他人のコミットを消してしまった場合、消されたコミットのハッシュを 相手が把握していれば、相手のローカルに残っている履歴からgit pushし直してもらうのが最も確実な復旧方法です。だからこそ、git push --forceではなくgit push --force-with-leaseを使う習慣をつけておけば、そもそも事故を未然に防げます。
4. チーム開発で事故を減らす運用のコツ
コマンド単体の知識に加えて、チームの運用ルールを整えておくと事故の発生率そのものを下げられます。
- コミットメッセージ規約 — Conventional Commits(feat: / fix: / docs: / refactor: / chore: など)に プレフィックスを揃えると、履歴を見ただけで変更の意図が分かり、
git revertやgit cherry-pickで対象コミットを探しやすくなります - 1ブランチ=1つの関心事 — feature/xxxブランチに無関係な変更を混ぜないルールを徹底すると、 問題が起きたときにrevertやcherry-pickで該当箇所だけを扱いやすくなります
- Pull Requestを必須にする — developやmainへの直接pushを禁止し、 レビューを経由させることで、危険なコマンドの結果が共有ブランチに直接反映されるのを防げます
- 保護ブランチの設定 — GitHub・GitLabのブランチ保護機能でforce pushや削除を禁止しておけば、 コマンドの誤操作自体をそもそも実行できなくできます
CI/CDの設定ファイルとあわせてチーム内のルールを統一したい場合は、CI/CD設定比較ツールでGitHub Actions・CircleCI・GitLab CIの構文差を確認しながら、ブランチごとの自動チェックを整備するのもおすすめです。
5. ブラウザで動くGitコマンド逆引き検索を使う
ここまで紹介したコマンドはあくまで代表例です。実際の開発では 「特定のファイルだけ過去のコミットに戻したい」「タグを打ち直したい」「マージを取り消したい」など、 もっと細かい「やりたいこと」に直面します。Gitコマンド逆引き検索は目的やキーワードで検索すると、該当コマンドの構文・実行例・安全(safe)・要注意(caution)・危険(danger)の3段階の安全度がまとめて表示されるツールです。検索した内容がサーバーに送信されることはなく、 すべてブラウザ内で完結します。ターミナルでコマンドを打つ前に、シェルコマンド横断検索と合わせて使えば、Git以外のコマンド操作もまとめて確認できます。
まとめ
- Gitコマンドは名前を暗記するより「やりたいこと」から逆引きする方が実務では役立つ
- reset --hard・push --force・checkout .のような履歴やファイルを直接書き換えるコマンドは危険と覚えておく
- 共有ブランチではrevert・restore・stashのような安全な操作を優先する
- やらかした後もgit reflogでHEADの移動履歴をたどれば復元できることが多い
- コミットメッセージ規約とブランチ保護を整えるとチーム開発の事故率を下げられる
- 安全度付きで確認したいときはGitコマンド逆引き検索が便利