Op Log di jj: Jaring Pengaman yang Bikin Berani Rebase
Setiap perintah jj tercatat di op log, dan catatan itu yang membuat eksperimen dengan history jadi murah.
Hari kedua pakai jj di repo internal core kami, saya menjalankan jj squash --into ke sebuah revisi yang barusan di-rebase. Perintahnya sukses, tidak ada error. Tapi waktu saya cek, kontennya tidak pindah ke mana-mana. Revisi tujuan yang saya pegang ternyata sudah jadi versi lama, karena rebase barusan sudah menulis ulang semuanya.
Di git, momen seperti ini biasanya berakhir di git reflog, menebak-nebak SHA mana yang benar, sambil berharap belum ada yang di-garbage-collect. Di jj saya cukup buka catatan operasi, lihat commit lama yang isinya masih utuh, lalu jj restore --from <commit lama>. Lima menit, selesai.
Catatan operasi itu namanya op log. Artikel ini cuma membahas satu hal itu.

Apa yang dicatat
Setiap perintah jj yang mengubah repo menghasilkan satu operasi. Tiap operasi menyimpan perintah yang dijalankan, kapan, dan keadaan seluruh repo sebelum dan sesudahnya. Termasuk jj undo sendiri, yang juga tercatat sebagai operasi.
jj op log
Hasilnya daftar operasi dari yang terbaru, masing-masing dengan ID. Selama 1,5 hari pertama, repo kami mencatat sekitar 167 operasi. Semua angka di artikel pembuka seri ini saya ambil dari sana, karena saya sendiri tidak ingat jam berapa melakukan apa. Op log ingat.
Kalau mau lihat detail satu operasi, commit mana yang berubah dan jadi apa:
jj op show <op-id>
Perlakukan op log sebagai version control untuk version control kamu.
Tiga cara mundur
Yang paling sering dipakai:
jj undo
Membatalkan operasi terakhir. Dijalankan lagi, dia mundur satu langkah lagi, dan seterusnya. Kelewatan? jj redo maju lagi. Rasanya persis Ctrl+Z dan Ctrl+Shift+Z di editor teks.
Masalahnya, undo menghitung operasi, tidak menghitung waktu. Kalau kamu habis reorganisasi stack dua belas langkah dan mau balik ke keadaan sebelum semuanya, menekan undo dua belas kali itu rawan salah hitung. Untuk kasus ini ada:
jj op restore <op-id>
Repo langsung kembali ke keadaan persis di operasi itu. Restore-nya sendiri tercatat sebagai operasi baru, jadi kalau ternyata salah pilih ID, kamu masih bisa undo restore-nya.
Kebiasaan yang saya ambil dari sini: sebelum kerja yang berisiko (rebase besar, split berkali-kali, pindah banyak bookmark), catat dulu ID operasi terakhir.
jj op log --limit 1
Satu ID itu tiket pulang. Kalau semuanya kacau, jj op restore ke sana dan anggap eksperimennya tidak pernah terjadi.
Skenario yang tertolong: rebase yang mendarat di tempat salah, jj abandon ke change yang keliru, resolusi konflik yang ternyata membuang baris penting, stack yang diacak-acak dan tidak jadi lebih baik. Semuanya bisa dibatalkan per langkah, atau di-restore ke titik awal sekaligus.
Undo untuk satu langkah yang salah. Restore untuk satu sore yang salah.
Beda dengan reflog
Orang pindahan git biasanya bertanya, “Ini reflog, kan?” Mirip, tapi cakupannya lain.
| git reflog | jj op log | |
|---|---|---|
| Yang dicatat | pergerakan HEAD dan ref | keadaan seluruh repo |
| Jumlah sejarah | satu per ref | satu untuk semua |
| Umur | kedaluwarsa (default 90 hari) | tetap sampai dibuang manual |
| Cara pulih | cari SHA, reset manual | jj undo atau jj op restore |
Reflog menjawab “HEAD pernah di mana saja”. Op log menjawab “repo ini pernah dalam keadaan apa saja”. Yang kedua jauh lebih berguna waktu yang rusak bukan cuma satu branch, tapi enam bookmark yang baru dipindah serentak.
Batasnya
Op log bukan sulap. Ada empat batas yang perlu kamu tahu sebelum terlalu percaya diri.
Op log itu lokal. Klon baru mulai dengan op log kosong, dan op log laptop saya tidak ada di laptop rekan satu tim.
Push tidak bisa di-undo. jj undo mengembalikan keadaan lokal, tapi commit yang sudah sampai GitLab tetap di sana. Perbaikannya force-push versi yang benar, dengan semua sopan santun yang menyertainya.
Undo menghitung operasi, jadi satu snapshot otomatis working copy juga dihitung satu. Kalau hasil undo terasa aneh, buka jj op log dulu sebelum menebak.
jj op abandon itu final. Perintah ini membuang sejarah operasi untuk menghemat ruang, dan yang sudah dibuang tidak bisa dipanggil lagi.
Sudut agen
Di repo kami, beberapa agen AI jalan paralel. Op log jadi kotak hitam: kalau ada yang aneh, saya bisa lihat persis agen mana menjalankan apa, jam berapa. Waktu dua proses jj split jalan di @ yang sama, op log mencatat “reconcile divergent operations” tiga kali. jj merekonsiliasi sendiri, dan saya tahu itu terjadi karena tercatat, tidak karena menebak.
Konsekuensinya satu aturan: jangan jj undo sembarangan di repo yang dipakai bersama agen lain. Operasi terakhir belum tentu punyamu. Cek jj op log dulu, pastikan yang mau dibatalkan memang operasi yang kamu maksud, baru undo atau restore.
Kotak hitam yang tidak dibaca cuma jadi pemberat.
Satu hal yang perlu diingat
Di jj, mencoba dulu lalu memutuskan belakangan itu murah, asal kamu tahu ID operasi tempat pulang.
Artikel berikutnya: enam kesalahan yang biasa dibuat orang pindahan git, termasuk satu yang langsung mematikan jaring pengaman ini.
Bahan dasar: panduan Operation Log di lazyjj.dev oleh Ernesto Jiménez.