Pernah tidak, kamu baru saja menjalankan git push, lalu sadar ada bug fatal di commit yang barusan kamu kirim? Atau lebih parah lagi, kamu commit di branch yang salah karena lupa ganti branch? Kepanikan ini pasti familiar. Git memang menyediakan cara untuk "menarik kembali" commit, tapi di sinilah dua perintah yang sering membuat bingung muncul: git reset dan git revert.
Nama keduanya mirip, fungsinya sekilas sama-sama "undo". Tapi cara kerjanya sangat berbeda, dan salah pilih bisa berujung pada history yang berantakan untuk seluruh tim. Artikel ini akan mengupas perbedaan fundamental antara git reset dan git revert, bagaimana masing-masing bekerja, serta kapan kamu harus memakai yang mana.
Sebelum Mulai: Memahami 3 Area di Git
Supaya bisa mengerti kenapa reset dan revert berperilaku beda, kamu perlu paham bahwa Git sebenarnya mengelola tiga "area" file secara terpisah. Di dokumentasi resmi, ini disebut three trees.
| Area | Peran |
|---|---|
| HEAD | Snapshot commit terakhir; inilah parent commit selanjutnya |
| Index (Staging Area) | Calon commit berikutnya — file yang sudah kamu git add |
| Working Directory | File aktual di folder yang sedang kamu edit |
Kunci untuk memahami artikel ini adalah: git reset dan git revert menyentuh ketiga area ini dengan cara yang berbeda. Reset bisa memindahkan HEAD, mengubah index, bahkan menimpa working directory tergantung modenya. Revert justru bekerja di level yang lebih sederhana — membuat commit baru. Kita bedah satu per satu.
Apa Itu Git Reset?
Secara resmi, git reset mengatur ulang HEAD (dan branch yang ditunjuk HEAD) ke state tertentu. Analoginya seperti memundurkan timeline: kamu memindahkan penunjuk branch kembali ke commit yang lebih lama, seolah-olah beberapa commit terakhir tidak pernah ada di branch itu.
Ini poin penting yang harus kamu pahami sejak awal: reset mengubah history. Commit yang kamu "lewati" dengan reset akan hilang dari branch (walaupun sebenarnya masih bisa diselamatkan lewat reflog, yang akan kita bahas nanti).
git reset punya tiga mode utama yang menentukan sejauh mana perubahan dibawa: --soft, --mixed (default), dan --hard.
Mode --soft
Mode ini hanya memindahkan penunjuk HEAD. Index dan working directory tidak berubah — semua perubahan dari commit yang "dibuka" tetap berada di staging area.
git reset --soft HEAD~1
Setelah perintah ini, commit terakhir hilang dari branch, tapi file-file-nya tetap staged dan siap di-commit ulang. Use case yang paling umum: mengulang commit message yang salah ketik, atau menggabungkan beberapa commit (squash). Karena tidak ada yang dihapus, mode ini aman.
Mode --mixed (Default)
Ini adalah mode default. git reset tanpa flag apa pun berperilaku sama dengan git reset --mixed. Yang berubah: HEAD dan index. Working directory tetap utuh.
git reset HEAD~1
Perbedaannya dengan --soft: perubahan sekarang jadi unstaged. Jadi setelah reset, file yang tadinya di-commit akan kembali ke status belum di-git add. Mode ini berguna saat kamu ingin merombak apa saja yang masuk ke staging area, atau memisahkan beberapa file dari satu commit yang terlalu besar. Karena perubahan masih ada di working directory, mode ini juga aman.
Mode --hard
Ini mode yang perlu kamu hormati. git reset --hard memindahkan HEAD, me-reset index, dan menimpa working directory agar sama persis dengan commit target.
git reset --hard HEAD~1
Perubahan yang belum pernah di-commit akan hilang permanen. Dari dokumentasi resmi Git: "Overwrite all files and directories with the version from <commit>, and may overwrite untracked files. Tracked files not in <commit> are removed so that the working tree matches <commit>."
Bahkan file untracked pun bisa tertimpa. --hard adalah satu-satunya mode yang benar-benar bisa menghancurkan data — salah satu dari sedikit kasus di mana Git menghapus sesuatu tanpa bisa dikembalikan. Pro Git Book menyebutnya sebagai satu-satunya cara membuat perintah reset menjadi berbahaya.
Ringkasan dampak ketiga mode:
| Mode | HEAD | Index | Working Directory | Aman? |
|---|---|---|---|---|
--soft | Pindah | Tetap | Tetap | Ya |
--mixed (default) | Pindah | Reset | Tetap | Ya |
--hard | Pindah | Reset | Reset | TIDAK |
Apa Itu Git Revert?
Kalau git reset memundurkan timeline, git revert bekerja berbeda total. Sesuai definisi resminya, revert membuat commit baru yang membalikkan (reverse) perubahan dari commit yang kamu tunjuk.
git revert <commit-sha>
Git mengambil diff dari commit tersebut, menerapkan kebalikannya ke working tree, lalu membuat commit baru yang berisi pembalikan itu. Commit aslinya tetap ada di history. Kamu bisa bayangkan ini seperti Ctrl+Z yang tercatat: aksinya direkam sebagai commit baru, bukan menghapus commit lama. Inilah alasannya revert tidak mengubah history.
Dokumentasi resmi mencatat hal penting: revert membutuhkan working tree dalam keadaan bersih (tidak ada modifikasi dari HEAD). Kalau ada perubahan yang belum di-commit, Git bisa menolak atau menghasilkan conflict. Saat terjadi conflict, kamu punya subcommand untuk menanganinya: --continue untuk lanjut setelah resolve, --skip, --abort untuk membatalkan seluruh operasi, dan --quit.
Perbandingan: Reset vs Revert
Sekarang kita bandingkan keduanya secara langsung.
| Aspek | git reset | git revert |
|---|---|---|
| Mengubah history | Ya | Tidak |
| Membuat commit baru | Tidak | Ya |
| Aman untuk shared branch | Tidak | Ya |
| Bisa undo beberapa commit | Ya (reset ke commit target) | Ya (revert satu per satu atau range) |
| Working directory terpengaruh | Tergantung mode | Ya (menerapkan patch kebalikan) |
| Perlu force push | Ya (jika sudah di-push) | Tidak |
| Cara memulihkan | Via reflog (terbatas waktu) | Revert the revert |
Perbedaan yang paling menentukan ada di baris pertama. Reset menulis ulang history; revert menambah history. Ini bukan soal selera, tapi soal keamanan di branch yang dipakai banyak orang.
Aturan praktis yang bisa kamu bawa ke mana-mana:
- Commit belum di-push (lokal) → pakai
git reset - Commit sudah di-push / dipakai bersama tim → pakai
git revert
Kenapa? Kalau kamu reset commit yang sudah di-push dan kemudian force push, kamu mengubah history yang mungkin sudah di-pull oleh anggota tim lain. Hasilnya, mereka akan mengalami conflict dan kebingungan yang tidak perlu. Revert tidak punya masalah ini karena hanya menambah commit baru di atasnya.
Kapan Menggunakan Git Reset
Reset paling aman dan paling masuk akal digunakan pada commit yang masih lokal — belum kamu dorong ke remote.
Undo Commit Terakhir (Belum Push)
Ini kebutuhan paling umum. Kamu baru saja commit, lalu sadar ada yang salah. Karena commit-nya belum di-push, kamu bebas memilih mode sesuai yang kamu butuhkan.
# Undo commit, tapi pertahankan perubahan tetap staged
git reset --soft HEAD~1
# Undo commit, perubahan jadi unstaged (mode default)
git reset HEAD~1
# Undo commit, dan buang semua perubahan itu
git reset --hard HEAD~1
Pilih yang pertama kalau kamu ingin langsung memodifikasi dan commit ulang dengan pesan baru. Pilih yang kedua kalau kamu ingin melihat-lihat dulu apa yang berubah sebelum staging ulang. Yang ketiga — hati-hati — hanya kalau kamu benar-benar yakin ingin membuang semua perubahan itu.
Squash Beberapa Commit
Reset juga jadi alat yang rapi untuk menggabungkan beberapa commit menjadi satu. Ini sering dipakai sebelum push untuk merapikan history kerja sehari-hari.
git reset --soft HEAD~3
git commit -m "Menggabungkan tiga commit terakhir"
Kamu memutar balik tiga commit terakhir, menyimpan semua perubahannya di staging area, lalu membuat satu commit baru yang menggabungkan semuanya.
Unstage File
Reset dengan pathspec tidak memindahkan HEAD sama sekali — ia hanya meng-update index untuk file tertentu. Ini setara dengan membatalkan git add.
git reset HEAD <file>
Sejak Git 2.23, ada alternatif yang lebih modern dan lebih eksplisit: git restore --staged <file>, yang fungsinya identik untuk kasus unstage. Keduanya valid; pilih yang paling kamu pahami.
Kapan Menggunakan Git Revert
Revert adalah pilihanmu ketika commit yang bermasalah sudah sampai ke remote atau dipakai bersama tim.
Undo Commit yang Sudah Di-Push
Ini skenario paling umum untuk revert. Karena commit sudah konsumsi orang lain, kamu tidak boleh menulis ulang history — jadi kamu terapkan kebalikannya sebagai commit baru, lalu push.
git revert <commit-sha>
git push origin main
History tetap utuh, semua orang bisa git pull dengan aman, dan commit yang bermasalah tetap tercatat di history. Justru ini nilai lebihnya: kamu dapat audit trail lengkap tentang commit mana yang dibatalkan dan kapan.
Revert Merge Commit
Revert merge commit punya aturan khusus. Karena merge punya lebih dari satu parent, Git tidak tahu sisi mana yang harus dianggap sebagai garis utama (mainline). Kalau kamu coba revert tanpa menentukan parent, Git akan error: "commit X is a merge but no -m option was given."
git revert -m 1 <merge-commit-sha>
Flag -m 1 memberitahu Git bahwa parent pertama adalah mainline. Ini biasanya memang yang kamu inginkan.
Ada satu peringatan penting yang sering luput: setelah revert merge, branch yang sama tidak akan membawa perubahan itu lagi jika di-merge ulang. Dari dokumentasi resmi: "Reverting a merge commit declares that you will never want the tree changes brought in by the merge." Jadi kalau kamu revert sebuah merge, lalu belakangan ingin perubahan aslinya masuk kembali, kamu harus me-revert commit revert tersebut ("revert the revert").
Revert Beberapa Commit Sekaligus
Kamu bisa revert range commit, dan dengan flag -n (atau --no-commit), semua perubahan dikumpulkan tanpa auto-commit sehingga akhirnya jadi satu commit rapi.
git revert -n HEAD~3..HEAD
git commit -m "Revert tiga commit terakhir"
Ini membantu kalau kamu ingin membatalkan serangkaian commit tapi tetap menjaga history tetap bersih dengan satu entri revert.
Recovery: Cara Menyelamatkan Diri Setelah Reset yang Salah
Kabar baiknya, meskipun git reset --hard terdengar menakutkan, ada safety net. Git menyimpan log semua pergerakan HEAD di reflog. Jadi kalau kamu reset ke commit yang salah, kamu masih bisa kembali.
git reflog
# Cari entri sebelum reset terjadi
git reset --hard HEAD@{1}
git reflog menampilkan riwayat pergerakan HEAD. Setelah kamu menemukan SHA atau referensi HEAD@{n} sebelum reset, kamu bisa git reset --hard ke sana untuk memulihkan state sebelumnya.
Tapi reflog punya batasan yang wajib kamu tahu:
- Bersifat lokal — reflog tidak pernah dikirim ke remote. Jadi reflog di komputermu tidak membantu kalau kamu bekerja di mesin lain.
- Ada batas waktu — secara default, reflog kadaluarsa setelah 90 hari untuk commit yang masih reachable, dan 30 hari untuk yang unreachable. Setelah itu lewat
git gc, commit bisa benar-benar hilang. - Tidak menyelamatkan perubahan yang belum di-commit. File yang tidak pernah kamu
git addatau commit kehilangan jejaknya dari reflog. Unstaged changes itu hilang permanen.
Intinya: reflog adalah penyelamat, tapi bukan alasan untuk pakai reset --hard secara sembarangan.
Kesalahan Umum yang Harus Dihindari
Ada beberapa jebakan yang sering menimpa developer, terutama yang masih baru.
Reset --hard di shared branch lalu force push. Ini resep bencana. Kamu menulis ulang history yang sudah di-pull orang lain, yang berujung pada conflict dan kebingungan massal. Kalau commit sudah shared, mundurlah ke git revert.
Revert merge commit tanpa -m. Git akan langsung menolak dengan pesan error karena tidak tahu parent mana yang jadi mainline. Selalu tentukan -m 1 (atau parent yang sesuai).
Re-merge setelah revert merge. Seperti dijelaskan tadi, meng-merge ulang branch yang sama tidak akan mengembalikan perubahan yang sudah di-revert. Kamu harus me-revert revert-nya lebih dulu.
Mengira semua perubahan bisa dipulihkan setelah --hard. Ingat: reflog hanya menyimpan commit yang pernah ada. Perubahan yang belum pernah di-commit hilang selamanya. Jangan tertidur karena merasa punya jaring pengaman.
Penutup
Perbedaan intinya ringkas: reset menulis ulang history, revert menambah history. Kamu bisa menurunkan aturan praktisnya ke satu kalimat — commit lokal pakai git reset, commit yang sudah shared pakai git revert.
Sebelum menyentuh git reset --hard, luangkan satu detik untuk bertanya: apakah ini benar yang saya mau, dan apakah commit ini sudah dipakai orang lain? Jawaban dari dua pertanyaan ini biasanya sudah cukup menentukan pilihanmu.
Kalau kamu ingin mendalami lebih jauh, dokumentasi resmi Git adalah tempat paling andal. Mulai dari halaman git-reset dan git-revert, plus bab Reset Demystified di Pro Git Book untuk memahami tiga area Git secara lebih visual.
Fitur komentar belum diaktifkan oleh administrator.