導入
reset はコミットを なかったことにして 巻き戻しました。でも、すでに push して共有したコミットを消すと、みんなの履歴と食い違います。そこで、対象の変更を打ち消す 新しいコミットを積む のが git revert。履歴を消さずに「取り消した」という事実を残すので、共有済みでも安全です。
説明
バグを含んだコミットを作り、それを revert で打ち消してみます。
git init
git add .
git commit -m "C1"
echo "バグを含む変更" >> app.js
git add app.js
git commit -m "Add buggy feature"
git log --oneline
git revert HEAD
Revert "Add buggy feature" という 新しいコミット ができました。中身を見ると、さきほどの変更が打ち消されています。
cat app.js
git log --oneline
app.js は元に戻り、履歴には「バグ入りコミット」と「それを打ち消したコミット」の 両方 が残ります。これが reset(履歴ごと消す)との決定的な違いです。
flowchart LR
C1["C1"] --> C2["Add buggy feature"] --> R["Revert (打ち消し)"]
打ち消す変更のあとに 同じ場所を触ったコミット があると、revert でもコンフリクトが起きます。そのときは rebase と同じ流れ——ファイルを直して git add、そして git revert --continue で仕上げます(やめるなら git revert --abort)。
| 使い分け | 何をする | いつ使う |
|---|---|---|
git reset | 履歴を巻き戻す(コミットを消す) | まだ 共有していない 手元の取り消し |
git revert | 打ち消すコミットを 足す | すでに 共有した 変更の取り消し |
「共有済みなら revert、手元だけなら reset」と覚えておくと迷いません。revert は履歴を書き換えないので、チームのリポジトリに対して安全に打てるのが強みです。
やってみよう
Add buggy feature を作ってから git revert HEAD を実行し、Revert "..." コミットが積まれること、cat app.js で変更が打ち消されること、git log --oneline に元のコミットも残っていることを確認しましょう。
演習
直前のコミット(HEAD)を打ち消す revert コミットを作成してください。
ヒント1を見る
直前のコミットを打ち消すのは git revert HEAD です。
ヒント2を見る
git revert HEAD