Git Commit Kamu Salah? Ini Cara Benerinnya

Git Commit Kamu Salah? Ini Cara Benerinnya
Photo by ROMROM Garcia/Unsplash

Oke, jadi ceritanya kamu lagi asyik ngoding, terus commit, eh pas diliat lagi, ups, ada typo di pesan commitnya, atau malah ada file yang kelupaan di-add, atau yang lebih parah, kamu commit sesuatu yang harusnya nggak dikomit. Panik? Tenang, itu wajar banget! Setiap developer, dari yang newbie sampai yang udah jago, pasti pernah ngalamin yang namanya commit "kurang sempurna" atau bahkan "salah".

Untungnya, Git itu powerful banget. Dia punya cara-cara buat kita "mengoreksi" sejarah commit kita. Jadi, nggak usah khawatir kalau commit terakhir atau bahkan commit yang udah lama ternyata ada yang nggak beres. Git menyediakan alat buat 'beres-beres' sejarah biar kelihatan rapi dan profesional.

Kenapa sih penting banget punya sejarah commit yang rapi? Bukan cuma soal keren-kerenan aja lho. Sejarah commit yang bersih dan deskriptif itu penting banget buat:

  • Debugging: Kalau ada bug baru muncul, kamu bisa cek histori commit buat nemuin perubahan mana yang mungkin jadi penyebabnya. Kalau commitnya berantakan, nyari jarum di tumpukan jerami deh.
  • Kolaborasi: Pas kerja bareng tim, orang lain perlu ngerti apa yang kamu lakuin dari pesan commit kamu. Kalau pesannya jelas, mereka gampang ngikutin alurnya.
  • Review Code: Reviewer jadi lebih gampang memahami perubahan yang kamu buat.
  • Pembelajaran: Kamu sendiri bisa lihat kembali alur pengerjaan fitur atau perbaikan bug tertentu.

Nah, sekarang gimana caranya benerin commit yang udah kadung dibuat? Ada beberapa skenario umum dan Git punya jurus-jurusnya sendiri buat tiap skenario. Jurus yang paling sering dipake dan paling gampang buat benerin commit terakhir itu namanya git commit --amend. Sementara kalau mau benerin commit yang udah lama atau bahkan mau ngubah banyak commit sekaligus, jurusnya lebih ampuh lagi, namanya git rebase -i (interactive rebase). Ada juga jurus lain kayak git reset atau git revert, tapi kita fokus ke yang paling sering dipake buat "ngoreksi" ya.

Yuk, kita bahas satu per satu!

1. Benerin Commit Terakhir: git commit --amend

Ini nih, jurus yang paling sering dipake kalau kamu sadar ada yang salah sama commit yang BARU AJA kamu buat. Mungkin kamu baru aja ngetik git commit -m "Fix typo di halaman login" terus baru ngeh kalau typonya belum semua dibenerin, atau malah file yang typonya dibenerin belum di-add ke staging area.

Perintah git commit --amend itu intinya bakal menggantikan commit terakhir kamu dengan commit yang baru. Jadi, commit yang lama itu seolah-olah nggak pernah ada, diganti sama yang baru.

Ada beberapa cara pake git commit --amend:

Skenario A: Cuma Mau Ganti Pesan Commit Terakhir

Misalnya, pesan commit kamu cuma "update files" doang, padahal harusnya lebih deskriptif.

  • Pastikan kamu lagi di branch yang bener dan nggak ada perubahan yang belum di-commit.
  • Jalankan perintah ini:
bash
    git commit --amend
  • Nanti Git bakal ngebuka editor teks (tergantung settingan editor default Git kamu, bisa Vim, Nano, VS Code, dll). Di situ, kamu bakal liat pesan commit terakhir kamu.
  • Ubah pesannya sesuai keinginan kamu.
  • Save dan tutup editornya.
  • Git bakal ngeganti commit terakhir kamu dengan pesan baru itu. Commit hash (ID unik commit) yang lama juga bakal berubah.

Atau, kalau mau lebih cepat dan nggak perlu buka editor (cocok buat perubahan kecil), kamu bisa langsung tambahin opsi -m:

bash
git commit --amend -m "Pesan commit baru yang lebih jelas: Fix typo di form registrasi"

Skenario B: Lupa Nambahin Perubahan ke Commit Terakhir

Kamu udah commit, tapi ternyata ada file lain yang harusnya masuk ke commit itu, atau ada perubahan minor lain yang kelupaan di-stage dan di-commit barengan.

  • Pastikan kamu lagi di branch yang bener.
  • Lakukan perubahan yang kelupaan (misalnya nambahin file atau ngedit sesuatu).
  • Stage perubahan itu kayak biasa:
bash
    git add nama-file-yang-kelupaan
    # atau
    git add . # kalau mau stage semua perubahan baru
  • Sekarang, jalankan perintah amend, tapi kasih opsi --no-edit. Opsi ini gunanya biar Git nggak ngebuka editor pesan commit, jadi pesan commit yang lama bakal dipake lagi. Perubahan yang baru di-stage bakal digabungin sama isi commit terakhir.
bash
    git commit --amend --no-edit

Git bakal ngeganti commit terakhir kamu, isinya sekarang gabungan dari isi commit lama ditambah perubahan yang baru kamu stage. Pesan commitnya tetap sama. Commit hashnya tetap* berubah karena isinya berubah.

Skenario C: Lupa Nambahin Perubahan PLUS Mau Ganti Pesan Commit

Gabungan dari dua skenario di atas.

  • Lakukan perubahan yang kelupaan dan stage perubahannya (git add ...).
  • Jalankan git commit --amend (tanpa --no-edit):
bash
    git commit --amend
  • Git akan ngebuka editor, nunjukkin pesan commit yang lama. Di sini, kamu bisa ubah pesan commitnya.
  • Save dan tutup editor.
  • Commit terakhir kamu sekarang isinya perubahan yang baru kamu tambahin PLUS pesan commit yang baru. Commit hashnya juga berubah.

Penting Banget Soal git commit --amend dan git push:

Oke, git commit --amend ini gampang banget dipake buat benerin commit terakhir yang belum di-push ke remote repository (kayak GitHub, GitLab, Bitbucket, dll). Aman sentosa!

Tapi, kalau commit terakhir itu udah terlanjur kamu push ke remote repository, dan kamu melakukan amend di lokal kamu, berarti sejarah commit di lokal kamu beda dengan sejarah commit di remote. Commit yang udah kamu amend itu punya hash ID yang beda dari commit yang udah ada di remote.

Kalau kamu coba git push biasa setelah amend, Git bakal nolak dengan pesan error yang intinya bilang "history kamu beda nih sama di remote".

Untuk mengatasi ini, kamu harus melakukan force push:

bash
git push --force origin nama-branch-kamu
atau yang lebih disarankan:
git push --force-with-lease origin nama-branch-kamu

(Kita akan bahas --force-with-lease nanti ya, intinya ini lebih aman).

BAHAYA FORCE PUSH: Force push itu intinya "paksa remote repository untuk menerima sejarah commit lokal saya, meskipun itu menimpa sejarah yang ada". Ini berbahaya kalau kamu kerja dalam tim dan branch yang kamu force push itu dipake juga sama orang lain. Kenapa? Karena force push bisa aja menimpa commit yang mereka udah push setelah commit yang kamu benerin, tanpa mereka sadari. Ini bisa bikin history mereka "putus" atau kacau.

Jadi, aturan mainnya:

  • Kalau commitnya BELUM DIPUSH: Aman banget pake git commit --amend.
  • Kalau commitnya SUDAH DIPUSH ke branch PRIVATE kamu sendiri (nggak dipake orang lain): Masih relatif aman pake amend lalu force push.
  • Kalau commitnya SUDAH DIPUSH ke branch SHARING (dipake tim): HATI-HATI BANGET! Sebisa mungkin hindari amend dan force push. Kalau terpaksa, pastikan kamu ngerti risikonya dan/atau udah komunikasiin sama tim kamu. Alternatif amannya adalah pake git revert (nanti kita bahas sekilas).

2. Benerin Commit yang Udah Lama: git rebase -i

Gimana kalau yang salah itu bukan commit terakhir, tapi commit yang udah beberapa commit ke belakang? Atau kamu mau ngubah pesan beberapa commit sekaligus? Nah, ini saatnya pake jurus git rebase -i.

git rebase -i (interactive rebase) itu alat yang super powerfull buat ngedit sejarah commit kamu. Kamu bisa ngelakuin banyak hal, termasuk:

  • Mengubah pesan commit yang udah lama (reword).
  • Mengubah isi commit yang udah lama (nambahin/ngapus file, ngedit sesuatu) (edit).
  • Menggabungkan beberapa commit jadi satu (squash atau fixup).
  • Menghapus commit (drop).
  • Mengubah urutan commit.

Konsepnya gini: git rebase -i bakal ngebawa kamu "kembali ke masa lalu" ke titik sebelum commit-commit yang mau kamu edit. Terus, dia bakal "memutar ulang" commit-commit itu satu per satu, tapi kamu punya kesempatan buat "nyela" di tiap commit buat ngelakuin perubahan.

Cara pakenya:

bash
git rebase -i HEAD~N

Ganti N dengan jumlah commit terakhir yang mau kamu libatkan dalam proses rebase. Misalnya, kalau kamu mau ngedit commit ke-3 dari belakang (termasuk commit terakhir), berarti N-nya adalah 3. Jadi, perintahnya git rebase -i HEAD~3. Kamu juga bisa pake hash ID commit sebagai batas bawah, misalnya git rebase -i a1b2c3d artinya rebase interaktif dari commit a1b2c3d sampai commit terakhir.

Setelah menjalankan perintah itu, Git bakal ngebuka editor lagi. Di dalamnya, kamu bakal liat daftar commit yang akan diproses, dari yang paling lama di atas sampai yang paling baru di bawah (kebalikan dari git log). Tiap baris diawali dengan kata kunci (defaultnya pick). Contoh isinya kira-kira gini:

pick a1b2c3d Commit pertama fitur X
pick e4f5g6h Commit kedua (salah pesan?)
pick i7j8k9l Commit ketiga (lupa nambah file?)Rebase aaaa...zzzz onto bbbb...yyyy
# Commands:
p, pick = use commit
r, reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like "squash", but discard this commit's log message
x, exec = run command (the rest of the line) using shell
d, drop = discard commit

Bagian # Commands: itu penjelasannya. Kamu tinggal ganti kata kunci pick di depan commit yang mau kamu ubah dengan perintah yang sesuai (reword, edit, drop, dll).

Skenario D: Mengubah Pesan Commit yang Udah Lama (reword)

Misalnya commit dengan pesan "Commit kedua (salah pesan?)" itu pesannya mau kamu benerin jadi "Tambahkan validasi form".

  • Jalankan git rebase -i HEAD~N (sesuaikan N biar commit yang kamu mau masuk dalam daftar).
  • Di editor yang muncul, cari baris commit yang pesannya mau kamu ganti.
  • Ganti kata kunci pick di depan baris itu jadi reword.
diff
    - pick a1b2c3d Commit pertama fitur X
    - pick e4f5g6h Commit kedua (salah pesan?)
    - pick i7j8k9l Commit ketiga (lupa nambah file?)
    + pick a1b2c3d Commit pertama fitur X
    + reword e4f5g6h Commit kedua (salah pesan?) # <-- Ganti jadi reword
    + pick i7j8k9l Commit ketiga (lupa nambah file?)
  • Save dan tutup editor rebase.
  • Git bakal mulai proses rebase. Pas nyampe di commit yang kamu kasih reword, Git bakal PAUSE dan ngebuka editor lain, nunjukkin pesan commit yang lama.
  • Ubah pesan commitnya sesuai keinginan kamu ("Tambahkan validasi form").
  • Save dan tutup editor pesan commit.
  • Git bakal nge-rebase commit itu dengan pesan baru, lalu lanjutin ke commit berikutnya kalau ada, atau selesai kalau udah beres.

Selesai! Commit yang pesannya kamu reword sekarang punya pesan baru. Commit hashnya berubah* (dan semua commit setelahnya juga berubah hashnya karena sejarahnya berubah).

Skenario E: Mengubah Isi Commit yang Udah Lama (edit)

Misalnya commit "Commit ketiga (lupa nambah file?)" itu kamu lupa nambahin satu file atau ada typo di dalamnya.

  • Jalankan git rebase -i HEAD~N (sesuaikan N).
  • Di editor rebase, cari baris commit yang mau kamu ubah isinya.
  • Ganti kata kunci pick di depan baris itu jadi edit.
diff
    - pick a1b2c3d Commit pertama fitur X
    - pick e4f5g6h Commit kedua (salah pesan?)
    - pick i7j8k9l Commit ketiga (lupa nambah file?)
    + pick a1b2c3d Commit pertama fitur X
    + pick e4f5g6h Commit kedua (salah pesan?)
    + edit i7j8k9l Commit ketiga (lupa nambah file?) # <-- Ganti jadi edit
  • Save dan tutup editor rebase.
  • Git bakal mulai rebase dan PAUSE pas nyampe di commit yang kamu kasih edit. Git akan bilang Stopped at ... You can amend the commit now....
  • Nah, sekarang kamu ada di state persis setelah commit itu dibuat. Lakukan perubahan yang kamu mau (edit file, tambahin file baru, dll).
  • Stage perubahan kamu: git add nama-file-yang-diubah atau git add ..
  • Amandemen commit yang sedang di-edit pake git commit --amend. Kalau pesannya nggak mau diubah, tambahin --no-edit:
bash
    git commit --amend --no-edit # kalau cuma mau nambahin isi tanpa ganti pesan
    # atau
    git commit --amend # kalau mau nambahin isi plus ganti pesan
  • Setelah amend selesai, kamu udah beres ngubah commit itu. Kasih tau Git buat lanjutin rebase:
bash
    git rebase --continue
  • Git bakal lanjutin proses rebase untuk commit-commit berikutnya kalau ada. Kalau nggak ada, rebase selesai.

Commit yang kamu edit sekarang isinya udah sesuai. Commit hashnya berubah* (dan semua commit setelahnya juga).

Skenario F: Menghapus Commit (drop)

Kalau ada commit yang isinya ternyata nggak perlu atau malah bikin error, kamu bisa hapus.

  • Jalankan git rebase -i HEAD~N (sesuaikan N).
  • Di editor rebase, cari baris commit yang mau kamu hapus.
  • Ganti kata kunci pick di depan baris itu jadi drop.
diff
    - pick a1b2c3d Commit pertama fitur X
    - pick e4f5g6h Commit kedua (salah pesan?)
    - pick i7j8k9l Commit ketiga (lupa nambah file?)
    + pick a1b2c3d Commit pertama fitur X
    + pick e4f5g6h Commit kedua (salah pesan?)
    + drop i7j8k9l Commit ketiga (lupa nambah file?) # <-- Ganti jadi drop

Atau cara gampang lainnya, hapus aja satu baris commit itu dari editor rebase.

  • Save dan tutup editor rebase.
  • Git bakal nge-rebase tanpa memasukkan commit yang kamu drop.

Selesai! Commit itu udah hilang dari sejarah. Commit hash semua commit setelahnya berubah*.

Penting Banget Soal git rebase -i dan git push:

Sama seperti git commit --amend, git rebase -i itu merubah sejarah commit. Commit-commit yang kamu ubah (baik pesan, isi, urutan, atau yang kamu hapus/gabungkan) bakal punya hash ID yang baru. Karena itu, rebase ini juga berbahaya kalau dilakukan pada commit yang sudah dipush ke branch sharing.

Kalau kamu rebase commit yang sudah dipush, sejarah lokal kamu akan beda dengan remote. Kamu harus force push (git push --force atau git push --force-with-lease) untuk update remote. Dan lagi-lagi, ini berisiko buat tim kamu.

Jadi, aturan main git rebase -i:

  • Kalau commit-commitnya BELUM DIPUSH: Aman banget pake git rebase -i. Ini cara paling clean buat ngatur history sebelum dibagikan.
  • Kalau commit-commitnya SUDAH DIPUSH ke branch PRIVATE kamu sendiri: Masih relatif aman pake rebase -i lalu force push.
  • Kalau commit-commitnya SUDAH DIPUSH ke branch SHARING: Sangat sangat HATI-HATI! Hampir selalu lebih baik pake git revert daripada rebase commit yang sudah dibagikan. Kalaupun terpaksa rebase, pastikan semua tim ngerti dan siap dengan konsekuensinya (misalnya mereka harus melakukan git pull --rebase setelah kamu force push).

Alternatif Lain: git revert

Selain amend dan rebase, ada juga git revert. Perintah ini gunanya untuk membuat commit baru yang isinya mengundo atau membatalkan perubahan dari commit tertentu.

Misalnya, ada commit "Add new feature X" yang ternyata bikin bug parah. Daripada ngutak-ngatik history pake rebase, kamu bisa aja revert commit itu:

bash
git revert hash-id-commit-yang-salah

Git bakal ngebuka editor buat kamu nulis pesan commit untuk commit revert ini (pesan defaultnya biasanya udah cukup jelas, bilang kalau commit ini mengembalikan perubahan dari commit X). Setelah kamu save dan tutup editor, Git bakal bikin commit baru yang isinya kebalikan dari commit "Add new feature X".

Keunggulan git revert:

  • TIDAK MERUBAH SEJARAH. Ini cuma nambahin commit baru. Commit-commit yang lama tetap ada dengan hash ID aslinya.
  • Aman buat branch sharing. Karena nggak merubah sejarah, kamu bisa push commit revert ini kayak push commit biasa tanpa perlu force push dan tanpa mengacaukan history anggota tim lain.

Kelemahan git revert:

  • Sejarah commit kamu jadi ada commit revert yang kadang bikin history kelihatan "mundur-maju".
  • Kalau kamu revert sebuah commit, lalu di masa depan kamu memutuskan untuk "mengembalikan" perubahan yang di-revert tadi, itu bisa jadi agak tricky (biasanya kamu harus revert commit revert-nya lagi).

Intinya, kalau kamu kerja di branch sharing dan udah push commit, git revert seringkali jadi pilihan yang lebih aman dan disarankan dibandingkan git rebase -i atau git commit --amend diikuti force push.

Memahami --force vs --force-with-lease Saat Force Push

Kalau kamu memutuskan untuk force push setelah merubah history (pake amend atau rebase), kamu punya dua opsi: --force dan --force-with-lease.

  • git push --force: Ini jurus paling brutal. Git akan MENIMPA sejarah di remote repository dengan sejarah lokal kamu, tanpa peduli apakah ada perubahan baru di remote yang mungkin belum ada di lokal kamu (misalnya ada anggota tim lain yang nge-push ke branch yang sama sementara kamu lagi ngoprek rebase). Ini bisa bikin perubahan orang lain hilang kalau nggak hati-hati.

git push --force-with-lease: Ini jurus force push yang lebih "santun". Git hanya akan menimpa sejarah di remote JIKA DAN HANYA JIKA sejarah di remote itu sama persis dengan sejarah remote terakhir kali kamu pull/fetch. Artinya, kalau ada anggota tim lain yang nge-push perubahan baru ke branch itu setelah* kamu terakhir kali sinkronisasi dengan remote, force-with-lease akan GAGAL. Ini ngasih kamu "lease" (izin) buat force push hanya jika nggak ada orang lain yang "menyewa" (menambah) ke branch itu sejak kamu terakhir ngintip. Ini jauh lebih aman di lingkungan tim karena mencegah kamu nggak sengaja menimpa pekerjaan orang lain.

Jadi, kalau memang terpaksa force push di branch sharing, selalu pake --force-with-lease. Kalau di branch pribadi, --force masih oke, tapi membiasakan pake --force-with-lease itu lebih baik.

Tips Tambahan Biar Jarang Salah Commit

Meskipun Git ngasih alat buat benerin commit, lebih baik lagi kalau kita bisa meminimalkan kesalahan dari awal. Beberapa tips nih:

  1. Stage dengan Hati-hati: Sebelum commit, selalu cek dulu apa aja yang udah kamu stage. Pake git status buat liat file mana aja yang diubah dan mana yang udah di-stage. Pake git diff --cached buat liat perubahan spesifik yang udah kamu stage (yang bakal masuk ke commit). Ini krusial banget buat mastiin nggak ada file kelupaan atau file nggak sengaja ke-add.
  2. Review Pesan Commit: Sebelum finalisasi commit (misalnya pas editor muncul), luangin waktu sebentar buat baca lagi pesan commitnya. Udah jelas dan deskriptif belum? Udah sesuai sama perubahannya belum?
  3. Commit Kecil & Sering: Jangan tunggu sampe perubahan numpuk banyak banget baru commit. Commit perubahan kecil dan terkait erat. Ini bikin commit history lebih gampang diikuti, dan kalau ada yang salah, ruang lingkup perbaikannya nggak terlalu besar.
  4. Gunakan Branch Baru: Untuk fitur atau perbaikan bug yang signifikan, selalu bikin branch baru. Kerja di branch sendiri itu lebih aman buat ngoprek-ngoprek sejarah pake rebase sebelum akhirnya di-merge atau di-rebase ke branch utama (kayak main atau develop).

Kesimpulan

Benerin commit yang salah itu hal yang sangat umum dalam workflow Git. Git ngasih kita alat yang powerful: git commit --amend buat commit terakhir, dan git rebase -i buat commit yang udah lama. Penting banget buat ngerti kalau kedua perintah ini merubah sejarah commit.

Perubahan sejarah commit itu aman kalau cuma di lokal kamu atau di branch pribadi yang belum dibagikan. Tapi, kalau history yang mau kamu ubah itu sudah terlanjur dipush ke branch yang dipake bareng tim, kamu HARUS HATI-HATI BANGET karena butuh force push yang bisa mengacaukan workflow tim lain. Dalam skenario ini, git revert seringkali jadi alternatif yang lebih aman karena dia nggak merubah sejarah, cuma menambahkan commit baru yang membatalkan perubahan sebelumnya.

Jangan takut buat nyoba perintah-perintah ini di repository lokal yang cuma buat latihan. Practice makes perfect! Makin sering kamu pake dan pahami, makin PD kamu ngadepin commit yang 'kurang pas'. Selamat mencoba!