git reset dan git revert sama-sama membatalkan commit, tapi caranya beda jauh. git reset memundurkan branch, seolah commit-nya gak pernah dibuat. git revert membuat commit baru yang membalik isi commit lama. Bayangin koran yang salah cetak harga. Koran yang sudah sampai di rumah pembaca gak bisa ditarik lagi, jadi besoknya terbit ralat: itu revert. Draf di mejamu sendiri, yang belum dikirim ke siapa pun, boleh kamu sobek dan tulis ulang: itu reset.
🧪 Tebakan cepat: setelah
git reset --soft HEAD~1, perubahan dari commit yang dibatalkan ada di mana: hilang, di staging area, atau cuma di working directory? Tebak dulu, jawabannya ada di bagian "Tiga mode reset".
Contoh: harga yang salah
Repo toko-kue punya 3 commit. Commit terakhir, c9e1f47 ubah harga, mengubah menu.html dari Kue lapis Rp15.000 jadi Kue lapis Rp18.000. Ternyata harganya gak jadi naik.
$ git log --oneline
c9e1f47 (HEAD -> main) ubah harga
b2d4f60 tambah menu
a1c3e5f halaman awal
- HEAD adalah penanda "kamu sedang di sini": branch aktif dan commit terakhirnya. Sekarang HEAD ada di
main, dic9e1f47. HEAD~1artinya satu commit sebelum HEAD, yaitub2d4f60.HEAD~2dua commit sebelumnya,a1c3e5f.- Ingat tiga tempat yang dipakai Git: working directory (file di folder kerjamu), staging area (yang sudah di-
git add, siap masuk commit berikutnya), dan repository (commit-commit-nya).
Tiga mode reset
git reset <mode> HEAD~1 selalu memindahkan main (dan HEAD) mundur ke b2d4f60, jadi c9e1f47 hilang dari git log. Modenya menentukan nasib perubahan Rp18.000:
| Mode | main pindah ke |
Staging area | menu.html di working directory |
git status |
|---|---|---|---|---|
--soft |
b2d4f60 | Rp18.000 | Rp18.000 | modified: menu.html di Changes to be committed |
--mixed (default) |
b2d4f60 | Rp15.000, sama dengan commit | Rp18.000 | modified: menu.html di Changes not staged for commit |
--hard |
b2d4f60 | Rp15.000 | Rp15.000 | nothing to commit, working tree clean |
$ git reset --soft HEAD~1
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: menu.html
Itu jawaban tebakannya: dengan --soft, perubahannya tetap di staging area, siap di-commit ulang.
--softcuma memindahkan branch. Staging dan file-mu gak disentuh. Cocok kalau kamu mau commit ulang dengan pesan atau isi yang lebih baik. Perintahnya gak mencetak apa-apa.--mixedjuga menyamakan staging dengan commit tujuan, tapi file-mu tetap. Perubahannya jadi "modified, belum di-add", jadi kamu bisa memilih ulang apa yang di-git add.git reset HEAD~1tanpa mode artinya--mixed. Git mencetakUnstaged changes after reset:laluM menu.html.--hardmenyamakan staging dan working directory dengan commit tujuan. Git mencetakHEAD is now at b2d4f60 tambah menu. Perubahan yang belum di-commit hilang, dan Git gak punya cara mengembalikannya.
Satu lagi: mau mengeluarkan satu file dari staging tanpa memundurkan commit? git restore --staged menu.html, atau cara lamanya git reset HEAD menu.html.
git revert: membatalkan dengan commit baru
Kembali ke 3 commit tadi. Kali ini batalkan dengan revert:
$ git revert c9e1f47
[main 5d2a8b0] Revert "ubah harga"
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline
5d2a8b0 (HEAD -> main) Revert "ubah harga"
c9e1f47 ubah harga
b2d4f60 tambah menu
a1c3e5f halaman awal
- Revert membuat commit baru,
5d2a8b0, yang isinya kebalikanc9e1f47:menu.htmlkembaliRp15.000. Hash commit-mu nanti beda. c9e1f47tetap ada di history. Gak ada yang dihapus, cuma ditambah.- Revert bisa membatalkan commit mana pun, gak harus yang terakhir:
git revert <hash>. - Git membuka editor untuk pesan commit-nya. Pesan bawaannya sudah cukup, simpan saja. Mau tanpa editor?
git revert --no-edit c9e1f47.
Reset atau revert?
| Situasi | Pakai |
|---|---|
| Commit sudah di-push dan mungkin sudah di-pull tim | git revert <hash> |
| Belum di-push, mau commit ulang dengan pesan atau isi yang lebih rapi | git reset --soft HEAD~1 |
| Belum di-push, mau memilih ulang file yang di-commit | git reset HEAD~1 (--mixed) |
| Belum di-push, mau membuang commit dan perubahannya | git reset --hard HEAD~1 |
Kenapa reset jangan dipakai di branch yang sudah di-push? main-mu jadi di belakang origin/main, jadi push biasa ditolak, persis seperti di pelajaran push. Kalau kamu paksa dengan --force, commit itu hilang dari GitHub, padahal temanmu masih memilikinya, dan dia akan masuk lagi waktu mereka merge. Revert cuma menambah commit, jadi aman untuk semua orang.
⚠️ Jebakan yang sering ketemu
--harddengan pekerjaan yang belum di-commit. Perubahan itu hilang permanen. Sebelum--hard, cekgit statusdulu.- Salah hitung
HEAD~.HEAD~1membatalkan 1 commit,HEAD~3membatalkan 3 commit sekaligus. Cekgit log --onelinesebelum reset. - Reset di branch bersama. Push-mu bakal ditolak. Jangan dipaksa dengan
--force, pakaigit revert. - Bingung di editor revert. Git sering membuka Vim. Ketik
:wqlalu Enter untuk menyimpan pesan bawaannya, atau pakai--no-edit.
TL;DR: git reset <mode> HEAD~1 memundurkan branch satu commit dan menghapusnya dari history. --soft: perubahannya tetap di staging area. --mixed (default): perubahannya ada di working directory, belum di-add. --hard: semua perubahan dibuang. git revert <hash> membuat commit baru yang membalik commit itu, dan history-nya tetap utuh. Belum di-push: reset boleh. Sudah di-push: pakai revert.