Undo di Git: restore, reset, revert, amend & reflog

Untuk membatalkan perubahan di Git, pilih perintah berdasarkan di mana perubahan itu berada. Perubahan yang belum di-commit dibatalkan dengan git restore. Commit lokal yang belum d...

Undo di Git: restore, reset, revert, amend & reflog
Iklan

Untuk membatalkan perubahan di Git, pilih perintah berdasarkan di mana perubahan itu berada. Perubahan yang belum di-commit dibatalkan dengan git restore. Commit lokal yang belum di-push bisa dibatalkan dengan git reset (soft, mixed, atau hard) atau diperbaiki dengan git commit --amend. Commit yang sudah di-push ke branch bersama sebaiknya dibatalkan dengan git revert, karena perintah ini membuat commit baru tanpa menulis ulang riwayat. Jika ada yang terlanjur hilang, git reflog hampir selalu bisa menyelamatkannya.

Artikel ini khusus membahas cara "undo" di Git, lengkap dengan tabel keputusan di bagian akhir. Semua perintah memakai sintaks Git modern (versi 2.23 ke atas, saat git restore dan git switch diperkenalkan).

Peta singkat: tiga area di Git

Memahami undo jauh lebih mudah jika Anda ingat tiga tempat perubahan bisa berada:

Iklan
  • Working directory: file yang sedang Anda edit.
  • Staging area (index): perubahan yang sudah di-git add dan siap di-commit.
  • Repositori (riwayat commit): perubahan yang sudah di-commit, ditunjuk oleh HEAD dan nama branch.

Setiap perintah undo bekerja pada satu atau beberapa area ini. Kebingungan biasanya muncul karena git reset bisa menyentuh ketiganya sekaligus tergantung opsinya.

git restore: membatalkan perubahan yang belum di-commit

Buang perubahan di working directory

git restore index.php
git restore .          # semua file di folder saat ini

File dikembalikan ke versi yang ada di staging area (atau ke commit terakhir jika belum di-stage). Perubahan yang dibuang dengan cara ini tidak bisa dipulihkan lewat Git, karena belum pernah tersimpan di commit. Pastikan Anda benar-benar tidak membutuhkannya.

Keluarkan file dari staging (unstage)

git restore --staged index.php

Perubahan tetap ada di file Anda, hanya saja tidak lagi masuk antrean commit. Ini aman dan tidak menghilangkan apa pun.

Ambil versi file dari commit tertentu

git restore --source=HEAD~2 config/app.php

Perintah ini mengembalikan isi satu file seperti pada dua commit sebelumnya, tanpa mengubah riwayat. Hasilnya muncul sebagai perubahan biasa yang bisa Anda commit.

Iklan

Pada Git versi lama, fungsi yang sama dilakukan dengan git checkout -- file dan git reset HEAD file. Keduanya masih berfungsi, tetapi git restore lebih jelas maksudnya.

File baru yang belum dilacak

git restore tidak menyentuh file yang belum pernah di-add. Untuk menghapusnya, gunakan git clean, dan selalu lihat dulu apa yang akan dihapus:

git clean -n    # simulasi: tampilkan daftar file
git clean -fd   # hapus file dan folder yang tidak dilacak

git commit --amend: memperbaiki commit terakhir

Lupa menambahkan file, atau pesan commit salah ketik? Selama commit tersebut belum di-push, --amend adalah cara paling rapi.

# ubah pesan commit terakhir
git commit --amend -m "Perbaiki validasi form registrasi"

# tambahkan file yang terlupa tanpa mengubah pesan
git add tests/RegistrasiTest.php
git commit --amend --no-edit

Penting dipahami: --amend tidak "mengedit" commit lama, melainkan membuat commit baru dengan hash berbeda dan mengganti commit terakhir. Jika commit lama sudah di-push, riwayat lokal dan remote akan berbeda, dan Anda harus force push. Untuk branch yang dipakai bersama, hindari ini. Tips menulis pesan commit yang baik sudah dibahas di artikel tersendiri, jadi di sini kita fokus pada cara membatalkannya.

Iklan

git reset: memundurkan branch

git reset <commit> memindahkan penunjuk branch saat ini ke commit lain. Opsi yang dipakai menentukan apa yang terjadi pada staging area dan working directory.

OpsiRiwayat (HEAD)Staging areaWorking directoryRisiko
--softMundurTetap (perubahan dari commit yang dibatalkan tetap ter-stage)TetapAman
--mixed (default)MundurDikosongkan sesuai commit tujuanTetap (perubahan jadi unstaged)Aman
--hardMundurDisamakanDisamakan; perubahan dibuangBerbahaya

reset --soft: gabungkan atau tulis ulang commit

git reset --soft HEAD~3
git commit -m "Tambah fitur ekspor laporan"

Tiga commit terakhir dibatalkan, tetapi semua perubahannya tetap ter-stage. Commit ulang, dan tiga commit kecil menjadi satu commit yang rapi. Ini cara sederhana untuk "squash" commit lokal tanpa rebase interaktif.

reset --mixed: batalkan commit, simpan perubahan

git reset HEAD~1

Commit terakhir dibatalkan, perubahannya kembali ke working directory sebagai perubahan yang belum di-stage. Cocok jika Anda ingin memecah satu commit besar menjadi beberapa commit, dengan git add per bagian.

reset --hard: buang commit dan perubahannya

git reset --hard HEAD~1
git reset --hard origin/main   # samakan persis dengan remote

Branch mundur dan semua perubahan, baik yang ter-stage maupun belum, ikut dibuang. Commit yang dibatalkan masih bisa diselamatkan lewat reflog, tetapi perubahan yang belum pernah di-commit akan hilang permanen. Sebelum menjalankan --hard, jalankan git status dan pertimbangkan git stash untuk berjaga-jaga.

Iklan

Notasi HEAD~ yang perlu diketahui

  • HEAD~1 atau HEAD~: satu commit sebelum HEAD.
  • HEAD~3: tiga commit sebelumnya.
  • Anda juga bisa memakai hash commit langsung, misalnya git reset --soft a1b2c3d.

git revert: membatalkan commit yang sudah di-push

Ketika commit sudah ada di remote dan mungkin sudah di-pull orang lain, menulis ulang riwayat dengan reset akan merepotkan seluruh tim. git revert menyelesaikan masalah ini dengan membuat commit baru yang isinya kebalikan dari commit yang ingin dibatalkan.

git revert a1b2c3d
git push

Riwayat tetap utuh dan jujur: siapa pun bisa melihat bahwa ada perubahan yang dibatalkan dan kapan. Tidak perlu force push.

Revert beberapa commit

# revert rentang commit tanpa langsung commit, lalu satukan
git revert --no-commit a1b2c3d^..f6e5d4c
git commit -m "Batalkan fitur diskon yang bermasalah"

Revert merge commit

Merge commit punya dua induk, jadi Git perlu tahu sisi mana yang dianggap "utama". Biasanya Anda memakai induk pertama, yaitu branch tempat merge dilakukan:

git revert -m 1 <hash-merge-commit>

Catatan penting: setelah merge di-revert, jika nanti Anda ingin me-merge ulang branch yang sama, Git menganggap commit-commit di branch itu sudah pernah masuk. Anda perlu me-revert commit revert tersebut terlebih dahulu agar perubahannya kembali.

Iklan

Jika revert menghasilkan konflik, cara menyelesaikannya sama seperti konflik merge biasa: perbaiki file, git add, lalu git revert --continue.

Membatalkan commit yang sudah di-push dengan aman

Ada dua skenario dengan solusi berbeda:

Dapatkan Update Terbaru

Berlangganan gratis. Artikel & tutorial coding terbaru langsung ke email kamu. Tanpa spam.

Branch bersama (main, develop)

Gunakan git revert. Ini satu-satunya pilihan yang tidak mengganggu orang lain. Banyak tim juga memproteksi branch utama sehingga force push memang tidak diizinkan.

Branch pribadi (feature branch yang hanya Anda pakai)

Anda boleh menulis ulang riwayat dengan reset atau amend, lalu push ulang dengan --force-with-lease:

Iklan
git reset --hard HEAD~1
git push --force-with-lease

--force-with-lease lebih aman daripada --force karena push akan ditolak jika remote ternyata berisi commit yang belum Anda lihat, misalnya rekan sempat push ke branch yang sama. Dengan --force biasa, commit mereka akan tertimpa tanpa peringatan.

Jika yang ter-push adalah data rahasia

Jika commit tersebut berisi password atau API key, revert tidak cukup karena isinya masih ada di riwayat. Ganti kredensial tersebut segera, lalu bersihkan riwayat dengan alat seperti git filter-repo. Untuk password baru yang kuat, Anda bisa memakai Password Generator.

git reflog: jaring pengaman terakhir

Reflog mencatat setiap pergerakan HEAD di repositori lokal Anda: commit, reset, checkout, rebase, amend. Artinya, commit yang "hilang" setelah reset --hard atau rebase yang kacau sebenarnya masih ada dan bisa ditemukan.

git reflog

Contoh keluaran:

Iklan
3f9a1c2 HEAD@{0}: reset: moving to HEAD~2
8d7e6b5 HEAD@{1}: commit: Tambah halaman laporan
c4b3a29 HEAD@{2}: commit: Tambah export CSV
...

Untuk kembali ke kondisi sebelum reset:

git reset --hard HEAD@{1}
# atau lebih aman: buat branch baru di commit tersebut
git branch penyelamatan 8d7e6b5

Membuat branch baru adalah pilihan yang lebih aman karena tidak mengubah apa pun di branch saat ini; Anda bisa memeriksa isinya dulu sebelum memutuskan.

Batasan reflog yang perlu diketahui:

  • Reflog hanya ada di repositori lokal, tidak ikut di-push atau di-clone.
  • Entri reflog kedaluwarsa. Secara default, entri untuk commit yang tidak lagi terjangkau dari branch mana pun disimpan 30 hari, dan entri lainnya 90 hari, sebelum dibersihkan oleh git gc.
  • Reflog tidak bisa memulihkan perubahan yang tidak pernah di-commit atau di-stash.

Tabel keputusan: perintah mana yang dipakai?

SituasiPerintahAman untuk branch bersama?
Ingin membuang edit di file yang belum di-stagegit restore fileYa (lokal saja)
Salah git addgit restore --staged fileYa (lokal saja)
Pesan commit terakhir salah, belum pushgit commit --amendHanya jika belum di-push
Lupa file di commit terakhir, belum pushgit add + git commit --amend --no-editHanya jika belum di-push
Ingin menggabungkan beberapa commit lokalgit reset --soft HEAD~N lalu commitHanya jika belum di-push
Batalkan commit tapi simpan perubahannyagit reset HEAD~1Hanya jika belum di-push
Buang commit lokal beserta perubahannyagit reset --hard HEAD~1Tidak
Batalkan commit yang sudah di-pushgit revert <hash>Ya
Batalkan merge yang sudah di-pushgit revert -m 1 <hash>Ya
Perbaiki commit di branch pribadi yang sudah di-pushreset/amend + git push --force-with-leaseTidak
Commit hilang setelah reset atau rebasegit reflog + git branch/git resetLokal saja

Kesalahan umum

  • Menjalankan git reset --hard saat masih ada perubahan yang belum di-commit, lalu kehilangan pekerjaan.
  • Melakukan amend atau reset pada commit yang sudah di-push ke branch bersama, kemudian force push dan menimpa pekerjaan rekan.
  • Memakai --force padahal --force-with-lease tersedia.
  • Mengira revert menghapus data rahasia dari riwayat.
  • Lupa opsi -m 1 saat me-revert merge commit, sehingga Git menolak perintahnya.
  • Menjalankan git clean -fd tanpa -n terlebih dahulu.
  • Panik dan meng-clone ulang repositori, padahal reflog di clone lama bisa memulihkan commit.

Ringkasan

  1. Belum di-commit: git restore (dan --staged untuk unstage).
  2. Commit terakhir perlu diperbaiki dan belum di-push: git commit --amend.
  3. Commit lokal ingin dibatalkan: git reset dengan --soft, --mixed, atau --hard sesuai kebutuhan.
  4. Sudah di-push ke branch bersama: git revert.
  5. Branch pribadi yang sudah di-push: tulis ulang lalu --force-with-lease.
  6. Sesuatu hilang: git reflog.

FAQ

Apa beda git reset dan git revert?

git reset memindahkan branch ke commit lama, seolah commit setelahnya tidak pernah ada (riwayat ditulis ulang). git revert membuat commit baru yang membatalkan efek commit lama, sehingga riwayat tetap utuh. Reset cocok untuk commit lokal, revert untuk commit yang sudah dibagikan.

Iklan

Bisakah memulihkan file setelah git restore?

Tidak lewat Git, karena perubahan yang belum di-commit tidak pernah tersimpan di repositori. Kemungkinan terakhir adalah fitur riwayat lokal di editor Anda (misalnya Local History di VS Code atau IDE JetBrains).

Bagaimana membatalkan git add .?

Jalankan git restore --staged .. Semua file keluar dari staging area, sementara isinya tetap seperti yang Anda edit.

Bagaimana membatalkan git revert?

Jika revert belum di-push, Anda bisa git reset --hard HEAD~1. Jika sudah di-push, revert commit revert-nya: git revert <hash-commit-revert>.

Apakah git reset --hard bisa dibatalkan?

Commit yang terbuang bisa dipulihkan lewat git reflog. Namun perubahan di working directory yang belum pernah di-commit atau di-stash tidak bisa dipulihkan oleh Git.

Iklan
undo git git reset vs revert git restore git reset hard git commit amend git reflog membatalkan commit git
Yudhi
Ditulis oleh

Yudhi

Web Developer

Web developer yang sehari-hari berkutat dengan PHP, Laravel, JavaScript, dan MySQL. Terbiasa membangun aplikasi web dari nol โ€” merancang database, menulis fitur, memburu bug, hingga deploy ke server โ€” lalu menuangkan solusi dan tutorialnya di DhieCoderWeb agar lebih mudah diikuti developer lain.

Bagikan artikel
Kembali

Komentar (0)

Punya pertanyaan atau tambahan? Tulis di bawah โ€” tak perlu login.

Membalas komentarโ€ฆ batal

Belum ada komentar. Jadilah yang pertama!

๐Ÿš€ Partner Recommendation

Butuh Source Code & Aplikasi Premium?

Download aplikasi Laravel, POS, Sekolah, Klinik, ERP, dan source code siap pakai di GudangCode.

GudangCode
  • โœ” Source Code Premium
  • โœ” Sistem Siap Pakai
  • โœ” Lifetime Update
  • โœ” Membership Lifetime
  • โœ” Update Aplikasi Harian
Daftar Membership โ†’
Iklan
Iklan