最近、Gitでリモートにプッシュ済みのコードを切り戻したいケースがあったので、復習です。
修正したコードを切り戻したいとき、git reset
と git revert
って何が違うんだっけ?と迷いますよね。
結論
細かいことは置いといて、まずは結論。
リモートにプッシュ済みのコードを切り戻したいとき
git revert
を使います。
手順:
- git revert <コミットハッシュ>
- git push origin <ブランチ名>
これでコミットが打ち消されて、かつリモート上に履歴も残ります。
コミットハッシュについては、git log
で確認できます。
% git log
commit aaxxd9bbexxcca773d50f8cf77d8b2xx14890806 (HEAD -> MY_APP-2, origin/MY_APP-2)
Author: Your Name <your.mail@gmail.com>
Date: Tue Oct 8 00:58:58 2024 +0900
コメント
ローカルのコミットを取り消したいとき
git reset
を使います。
手順:
- git reset
オプションなしで実行した場合、デフォルトでは--mixed
が適用されます。
通常、以下の順番でコミットしますね。
- ファイルを修正
- ステージング
- コミット
この状態でgit reset
を実行すると、1の状態、つまりステージング前の状態に戻ります。
基本的には、ここまでを覚えとけば大丈夫という認識。
reset と revert の違い
git reset
と git revert
はどちらもコミットの変更を元に戻すコマンドですが、異なる動作をします。
特徴 | git reset |
git revert |
---|---|---|
動作 | コミット自体を削除または移動する | 新しいコミットを作成して変更を元に戻す |
履歴 | 履歴を書き換える (危険性あり) | 履歴を書き換えない (安全) |
共同作業 | リモートブランチにプッシュ済みコミットをresetすると、共同作業者に影響を与える可能性が高い | リモートブランチにプッシュ済みコミットをrevertしても、共同作業者への影響が少ない |
用途 | ローカルでのミス修正、ブランチの整理 | 公開済みのコミットの修正、共同作業での変更元に戻し |
git reset
git reset
は、指定したコミットまでHEADを移動させます。
つまり、そのコミット以降の変更を履歴から削除します。
-
--soft
: 作業ツリーとインデックスには変更が残る。 -
--mixed
: 作業ツリーには変更が残るが、インデックスはクリアされる。 -
--hard
: 作業ツリーとインデックスの変更が完全に消える。(危険なオプション。元に戻した変更は完全に失われる)
例: git reset --hard HEAD~2
は、直近2つのコミットを完全に削除。
git revert
git revert
は、指定したコミット取り消す新しいコミットを作成します。元のコミットは履歴に残りますが、その変更は打ち消されます。公開済みのコミットを修正するのに最適。
例: git revert <コミットハッシュ>
は、指定されたコミットを元に戻す新しいコミットを作成。
まとめ
状況 | git reset |
git revert |
---|---|---|
ローカルでのミスを修正したい | 〇 | × |
公開済みのコミットを修正したい | × | 〇 |
ブランチを整理したい | 〇 | × |
共同作業で、公開済みコミットの変更を元に戻したい | × | 〇 |
履歴をクリーンにしたい (危険性あり) | 〇 | × |
git reset
は誤って使用すると履歴が破損する可能性があり、注意が必要。
公開済みのコミットに対しては、常にgit revert
を使用した方がいいですね。