- Bab 5 dari 8
- 30 menit
- 4 soal kuis
Riwayat, Diff, dan Membatalkan Perubahan
Di bab ini (9 bagian)
Tujuan bab ini
- Menelusuri riwayat dengan
git log,git show, dangit blame. - Membaca
git diffuntuk working directory, staging area, dan antar commit. - Memilih cara membatalkan yang tepat:
restore,commit --amend,revert, ataureset. - Memakai
git refloguntuk menyelamatkan commit yang "hilang".
Menelusuri riwayat dengan git log
Kamu sudah kenal git log --oneline. Ada beberapa opsi lain yang sering dipakai:
Contoh nyata dari repositori dengan tiga commit:
Filter bisa digabung, misalnya --author dengan --since. --graph --oneline --all adalah cara tercepat memahami bentuk cabang sebuah proyek, dan akan sering kamu pakai di bab berikutnya.
git show dan git blame
git show <hash> menampilkan satu commit lengkap: penulis, tanggal, pesan, dan diff-nya. Tanpa hash, yang ditampilkan adalah commit terakhir (HEAD).
git blame <file> menunjukkan siapa yang terakhir mengubah setiap baris, dan di commit mana:
Tanda ^ berarti baris itu berasal dari commit pertama. Blame bukan untuk mencari kambing hitam, tapi untuk menemukan commit yang tepat lalu membaca alasannya lewat git show.
git diff: apa bedanya?
git diff membandingkan baris demi baris. Yang dibandingkan tergantung opsinya:
| Perintah | Membandingkan |
|---|---|
git diff | working directory vs staging area (yang belum di-add) |
git diff --staged | staging area vs commit terakhir (yang akan masuk commit) |
git diff HEAD~2 HEAD | dua commit |
Baris berawalan - dihapus, + ditambahkan, dan baris tanpa tanda hanyalah konteks. Ini yang sering bikin bingung: setelah git add app.js, perintah git diff mendadak kosong. Perubahannya tidak hilang, tapi sudah pindah ke staging. Lihat dengan git diff --staged.
HEAD~1 artinya satu commit sebelum HEAD, HEAD~2 dua commit sebelumnya, dan seterusnya.
Membatalkan perubahan
Pilih alat sesuai di mana kesalahanmu berada:
| Situasi | Perintah | Tingkat bahaya |
|---|---|---|
| Edit berkas ngawur, belum di-add | git restore <file> | edit yang belum di-commit hilang |
| Salah add | git restore --staged <file> | aman, isi berkas tetap |
| Typo pesan, atau ada berkas tertinggal di commit terakhir | git commit --amend | menulis ulang commit terakhir |
| Commit lama yang sudah di-push ternyata salah | git revert <hash> | aman untuk publik |
| Mundur beberapa commit di branch lokal | git reset | hati-hati |
git restore mengembalikan berkas di working directory ke versi staging (atau commit terakhir). Perubahan yang belum di-commit benar-benar dibuang, jadi pastikan memang tidak dibutuhkan. Dengan --staged, yang dibatalkan hanya status add-nya, sementara isi berkas tetap utuh.
git commit --amend mengganti commit terakhir dengan versi baru:
Hash commit berubah, karena secara teknis itu commit baru. Aman dipakai selama commit tersebut belum di-push.
git revert membuat commit baru yang membalik efek commit lama. Riwayat tidak diubah, hanya ditambah:
Karena tidak ada commit yang hilang, rekan setim yang sudah menarik riwayat lama tidak akan bermasalah.
git reset memindahkan penunjuk branch ke commit lain. Ada tiga mode:
| Mode | Commit setelahnya | Staging | Working directory |
|---|---|---|---|
--soft | dibatalkan | perubahan tetap ter-stage | utuh |
--mixed (default) | dibatalkan | dikosongkan | utuh, perubahan jadi unstaged |
--hard | dibatalkan | dikosongkan | ditimpa, perubahan hilang |
Peringatan:
git reset --hardmenghapus perubahan yang belum di-commit secara permanen. Jangan pakaireset(atauamend) pada commit yang sudah di-push ke repositori bersama. Gunakangit revertsebagai gantinya.
git reflog: jaring pengaman
Commit yang "hilang" karena reset --hard sebenarnya masih ada untuk sementara. git reflog mencatat setiap pergerakan HEAD di laptopmu:
Untuk kembali ke posisi sebelum reset, cukup git reset --hard HEAD@{1} (atau pakai hash-nya). Reflog hanya ada di repositori lokal dan entri lama dibersihkan setelah beberapa waktu (umumnya 90 hari). Perubahan yang belum pernah di-commit tidak tercatat sama sekali, jadi reflog tidak bisa menyelamatkannya.
Kesalahan umum
- Panik karena
git diffkosong padahal sudah ada perubahan. Kemungkinan besar perubahannya sudah di-add. Cek dengangit diff --staged. - Memakai
reset --harduntuk membatalkan add. Yang benargit restore --staged.--hardikut membuang hasil editanmu. - Amend atau reset commit yang sudah di-push, lalu terpaksa force push. Rekan setim jadi punya riwayat yang berbeda. Untuk commit publik, pakai revert.
- Mengira revert menghapus commit. Commit lama tetap ada di log, dan revert menambah satu commit baru di atasnya.
- Lupa reflog. Sebelum menyerah karena commit "hilang", jalankan
git reflogdulu.
Coba sendiri
1. Buang editan yang belum di-add.
git diff menampilkan +// typo. Setelah restore, git status -s tidak mencetak apa pun.
2. Batalkan add tanpa kehilangan isi.
Buang lagi dengan git restore app.js.
3. Revert, lalu reset, lalu selamatkan dengan reflog.
Output dari reset, log, dan reflog (hash di laptopmu akan berbeda):
Commit revert hilang dari log, tapi masih tercatat di HEAD@{1}. Selamatkan:
Commit revert kembali lagi.
Rangkuman
git log(dengan--oneline,--graph,-p,--author,--since),git show, dangit blamedipakai untuk menelusuri riwayat.git diffmelihat perubahan yang belum di-add,--stagedmelihat isi staging, dan dua hash membandingkan antar commit.restoreuntuk berkas,restore --stageduntuk membatalkan add,amenduntuk commit terakhir yang belum di-push, danrevertuntuk commit publik.reset --hardbisa membuang kerjaan, dangit reflogadalah jalan pulang untuk commit yang terlanjur hilang.
Slide 15 sampai 16 dari deck Git. Penjelasan lengkapnya ada di mode Baca.

Selesaikan bab ini
- 1. Baca materi
- 2. Kuis (4 soal)
Cek pemahaman
1app.js sudah punya satu commit. Apa yang dicetak oleh git diff terakhir?
echo 'let x = 2;' > app.js git add app.js git diff2Commit lama yang sudah di-push ke repositori tim ternyata salah. Cara membatalkan yang aman adalah...
3Commit yang terbuang oleh git reset --hard HEAD~1 masih bisa ditemukan lewat git reflog.
4Apa output git status -s di akhir?
git commit -am "Ubah x" # mengubah app.js git reset --soft HEAD~1 git status -s