Jujutsu - Sistem kontrol versi terdistribusi yang sederhana dan kuat, kompatibel dengan Git
(github.com/martinvonz)- Jujutsu adalah sistem kontrol versi yang digunakan untuk menyalin kode, melacak perubahan, dan mempublikasikan perubahan pada proyek perangkat lunak, serta dirancang agar mudah digunakan dengan mempertimbangkan pengguna baru maupun berpengalaman, proyek pribadi baru maupun riwayat dan tim berskala besar
- Antarmuka pengguna dan algoritme kontrol versi dipisahkan secara internal dari sistem penyimpanan yang menyediakan konten, dan saat ini menggunakan repositori Git sebagai lapisan penyimpanan sehingga kompatibel dengan alat berbasis Git
- Di Git hanya commit dan file yang disimpan, sementara bookmark(branch) dan metadata tingkat atas lainnya disimpan di penyimpanan kustom di luar Git
- Backend Git default menggunakan pustaka Rust gitoxide, dapat mengambil branch dari repositori remote Git dan melakukan push ke remote, serta membuat commit yang terlihat seperti commit Git biasa
- Menggunakan model working-copy-as-a-commit yang merepresentasikan salinan kerja sebagai commit nyata, dan perubahan file otomatis dicatat sebagai commit biasa lalu di-amend setiap kali ada perubahan berikutnya
- Perintah tidak gagal hanya karena ada dirty working copy
- Tidak memerlukan
git stash - Bahkan sebelum pekerjaan selesai, Anda dapat menetapkan pesan commit pada commit working copy
- Semua operasi di repositori dicatat bersama snapshot status repositori setelah operasi, sehingga memungkinkan pemulihan status repositori sebelumnya, undo per operasi, dan revert untuk operasi tertentu yang bukan operasi terbaru
- Konflik dicatat sebagai objek kelas satu seperti commit, sehingga operasi yang memunculkan konflik tetap berhasil dan dapat ditangani kemudian melalui satu alur kerja penyelesaian konflik
- Saat commit diubah, semua descendant dari commit lama otomatis di-rebase ke atas commit baru, hasil penyelesaian konflik juga dipropagasikan ke descendant, dan bookmark serta working copy yang menunjuk ke commit yang di-rebase juga diperbarui
- Tidak ada index atau staging area yang eksplisit, pemilihan commit menggunakan bahasa revset, dan format output diproses dengan bahasa template yang dapat dikonfigurasi pengguna
- Menyediakan fitur penulisan ulang riwayat seperti
jj describeuntuk mengedit pesan commit apa pun,jj diffedituntuk mengedit perubahan commit tanpa checkout,jj splituntuk membagi commit, danjj squash -i --from X --into Yuntuk memindahkan sebagian perubahan ke commit lain - Fitur replikasi konkuren yang aman masih eksperimental, dirancang agar repositori tidak menjadi rusak saat menggunakan sistem file terdistribusi atau alat backup seperti Dropbox dan
rsync, dengan target terburuk berupa tereksposnya konflik antara status lokal dan remote jjadalah sistem kontrol versi eksperimental; kompatibilitas Git stabil, tetapi mungkin masih ada fitur yang sedang dikerjakan, UX yang belum optimal, dan celah alur kerja untuk pola penggunaan tertentu- Fungsinya sudah cukup matang, tetapi dukungan Git submodule belum selesai, masih ada beberapa bug performa, dan belum ada dukungan native untuk alur kerja berbasis email
- Sebelum 1.0.0, masih akan ada perubahan alur kerja dan perubahan format on-disk yang tidak kompatibel ke belakang; untuk perubahan format, akan diupayakan upgrade transparan atau menyediakan perintah/skrip upgrade saat diminta
- Merupakan perangkat lunak open source berlisensi Apache 2.0, bukan produk yang didukung Google, dan dukungan disediakan oleh komunitas
2 komentar
Jujutsu - DVCS kompatibel Git yang sederhana dan kuat
Saya pernah mengunggah ini satu setengah tahun lalu, dan sekarang topik ini muncul lagi di HN sebagai isu.
Komentar Hacker News
Senang melihat ini muncul di sini. Saya beralih ke jj sekitar 2–3 minggu lalu, dan rasanya tidak ingin kembali lagi. Cara kerja di kepala memang harus banyak diubah, tetapi alur yang disediakan
jjcukup saya sukaiWaktu untuk memikirkan secara terpisah apa yang akan di-commit jadi hilang, dan semua perubahan file otomatis tercermin dalam commit salinan kerja. Tentu kadang itu tidak diinginkan, jadi ada fitur untuk membagi commit menjadi dua atau memindahkannya, dan saya suka bahwa semua operasi bekerja terhadap commit
jj logsangat bagus untuk melihat peta lengkap dari beberapa branch, konflik bisa diselesaikan sebagian lalu berpindah ke branch lain, dan ID changeset yang dipersingkat juga nyaman. Misalnya, dijj logkita bisa melihat changeset yang akan di-rebase lalu menjalankanjj rebase -s qr -d master, yang lebih cepat daripada mengetik seluruh nama branchTertulis bahwa ini bisa dipakai dengan backend seperti Dropbox, tetapi akan bagus kalau ada sistem yang mudah dipakai dengan IPFS. Untuk data berukuran besar, kita tidak bisa menyimpan 1 TB di GitHub, dan LFS saya kesampingkan karena berbayar
Orang yang ingin memakai dataset toh akan memilikinya secara lokal, jadi IPFS, yang membuat sumber unduhan bukan satu melainkan ribuan, terasa sebagai solusi alami. Jika penyimpanan datanya memakai IPFS, saya akan langsung beralih, tetapi kalau tidak, menurut saya nilainya untuk ditelusuri jadi kecil
Jujutsu dimulai sebagai proyek pribadi penulisnya, dan sekarang menjadi proyek penuh waktu penulisnya di Google. Pernah dipresentasikan di Git Merge 2022
Jujutsu: A Git-Compatible VCS - Git Merge 2022:
Video:
https://youtu.be/bx_LGilOuE4
Slides:
https://docs.google.com/presentation/d/1F8j9_UOOSGUN9MvHxPZX...
Saya sudah memakai jj setiap hari selama hampir setahun, dan menurut saya jelas jauh lebih baik daripada pengalaman pengguna Git. Karena saya cukup sensitif soal membagi perubahan menjadi commit atomik, rebase otomatis adalah fitur kuncinya
Konflik bisa dicatat di dalam commit, sehingga tidak perlu berhenti di tengah rebase untuk memperbaiki konflik seperti di Git atau Mercurial. Walaupun commit diubah atau dihapus, jj otomatis me-rebase semua commit turunannya, dan berbeda dari Git rebase, ia juga menangani beberapa child seperti Mercurial evolve
Perintah dasar untuk menangani riwayat commit juga bagus. Dengan
jj move|restore, perubahan dari satu commit bisa dipindahkan atau disalin ke commit lain; denganjj split, commit bisa dipecah; dan denganjj rebase, commit bisa dipindahkan. Karena semuanya berada di dalam riwayat commit tanpa working tree atau index, semuanya bisa ditangani dengan perintah dan flag yang samaLog kerja juga sangat bagus, sehingga sebagian besar operasi bisa dikembalikan tanpa masalah. Ini kontras dengan Git, di mana untuk memperbaiki rebase buruk atau
commit --amend, kita harus mengorek commit yang tepat dari reflog dan memperbaiki ref secara manualHal yang paling mengganggu adalah commit salinan kerja otomatis kadang mencoba meng-commit file yang tidak diinginkan, dan tidak adanya deteksi penggantian nama, sehingga merge tidak ditangani seanggun Git. Meski begitu, commit yang rusak bisa diperbaiki relatif mudah dengan
jj split|restore, dan para pengembang jj juga sedang memikirkan masalah penggantian namaSaya senang bahwa meskipun hasil kerja memunculkan konflik, informasi itu dicatat di commit dan operasi dianggap berhasil, lalu konflik bisa diselesaikan nanti. Selama sekitar 10 tahun terakhir saya menangani algoritma penyuntingan kolaboratif, dan idealnya alat seperti Git pada akhirnya digantikan oleh pendekatan berbasis CRDT
Dengan CRDT, kita bisa melakukan pair programming memakai alat yang sama, dan merge rumit seperti konflik dengan diri sendiri yang bisa muncul di Git juga ditangani lebih baik. Ini juga model yang lebih kuat
Namun CRDT teks modern otomatis menyelesaikan penyuntingan bersamaan tanpa konflik, sementara saat berkolaborasi menulis kode secara offline, biasanya kita ingin konflik terlihat agar manusia menyelesaikannya sendiri. CRDT memiliki lebih banyak informasi riwayat penyuntingan daripada Git, jadi secara teori mungkin, tetapi untuk melakukannya dengan benar, sepertinya konflik itu sendiri harus dimasukkan ke model data file teks, dan saya kurang tahu bagaimana itu akan cocok dengan editor modern
Kedengarannya jj menemukan trik serupa, jadi saya menantikan seberapa baik ini bekerja dalam praktik. Rasanya seperti selangkah lebih dekat ke impian repositori kode berbasis CRDT
git bisectJika ada bug yang dapat direproduksi dan penyebabnya rumit, bukankah berguna menemukan commit mana yang memperkenalkan bug itu lalu melihat perubahan apa yang menjadi penyebabnya. Setidaknya bagus untuk mendapatkan intuisi awal tentang apa yang perlu diperbaiki
Saat ini
git bisectbekerja paling baik ketika semua commit bisa di-build dan dijalankan. Jika ada commit yang berisi penanda konflik sehingga tidak bisa di-build atau dijalankan, intervensi manual yang dibutuhkan menjadi jauh lebih banyakSaya penasaran bagaimana fungsi yang setara dengan
git bisectbisa diadaptasi untuk skenario seperti ini. Sekadar memindai string penanda konflik mungkin tidak tepat. Sebab dokumen bisa saja menjelaskan penanda konflik, atau dalam beberapa bahasa markup,=======bisa dipakai secara sah sebagai garis bawahIni tampak bertentangan dengan gagasan bahwa riwayat source management adalah artefak yang bermakna, dan bahwa kumpulan patch harus dirapikan menjadi rangkaian perubahan bertahap dan atomik sebelum meninggalkan mesin pengembang
Namun sebagian besar pengembang di sekitar saya sudah memperlakukan riwayat Git seperti riwayat undo editor yang tak terbatas, jadi pendekatan ini mungkin justru akan mengukuhkan kenyataan itu
Saya penasaran bagaimana Anda melihat riwayat jangka panjang bekerja, dan apakah itu akan lebih berguna atau kurang berguna dibanding sekarang
Salinan kerja yang otomatis di-commit awalnya terdengar bagus, tetapi ada banyak situasi yang tidak menyenangkan
Kalau ada file artefak baru yang muncul tetapi belum dimasukkan ke
.gitignore, file itu akan otomatis di-commit. Jika setelah menambahkan file ignore di satu branch lalu beralih ke branch lain, file tersebut tetap ada di salinan kerja tetapi tidak ada di.gitignore, sehingga bisa otomatis di-commitSelain itu, jauh lebih mudah men-stage hanya sebagian file lalu commit daripada memecah commit belakangan
Saya juga sudah terlanjur berpikir begitu, tetapi tidak tahu apakah itu benar-benar tepat. Dalam praktiknya, cukup sering kita memperbaiki indeks dan meng-amend commit setelahnya, dan itu juga bisa dilakukan sebelumnya
Kalau pengeditan setelahnya memang tidak bisa sepenuhnya dihindari, bukankah satu alur kerja tunggal untuk pengeditan semacam ini lebih baik? Saya belum mencobanya, tetapi pendekatan ini tampak cukup meyakinkan dalam mempertanyakan kebiasaan yang selama ini dianggap wajar, padahal mungkin sebenarnya tidak membantu
Saya tidak punya kasus penggunaan di mana semua file yang dibuat atau dimodifikasi selalu masuk ke commit
Menurut saya, ketika beralih ke branch lain lalu file tetap ada di salinan kerja tetapi tidak ada di
.gitignore, itu adalah kegagalan Git. Seharusnya ada semacam.local.gitignoreyang ditambahkan di atas.gitignore. File ignore yang hanya saya butuhkan sangat umum dan bukan sesuatu yang pantas masuk ke.gitignoreproyek. Ada caranya, tetapi semuanya terasa canggung, jadi semestinya disediakan secara sederhana secara defaultMeski begitu ini menarik. Saya tidak pernah menyukai staging di Git, tetapi belum pernah mengalami kasus yang disebutkan di sini, jadi baru sekarang saya memahami bahwa diperlukan tahap perantara antara sistem file dan commit
.gitignore, pada auto-commit berikutnya file tersebut akan dikeluarkan lagi dari commit salinan kerja anonimAlur di mana file masuk dulu ke commit salinan kerja anonim lalu keluar lagi, alih-alih tidak ditambahkan sejak awal, memang tidak intuitif. Namun jika commit anonim itu sebagian besar tidak terlihat oleh pengguna, sepertinya tidak ada bedanya
Kalau melihat dokumentasinya, beberapa kasus yang dikhawatirkan itu dibahas secara eksplisit:
https://github.com/martinvonz/jj/blob/main/docs/git-comparis...
Selain beberapa kasus khusus, sudah bertahun-tahun saya hampir tidak memakai Git dari command line. Dalam keseharian saya mengandalkan integrasi bawaan IDE seperti IntelliJ, dan sulit memahami mengapa orang sengaja menanggungnya secara manual
Di dalam editor, saya bisa memilih per baris untuk membuat partial commit, melihat semua branch, melakukan merge dan cherry-pick, commit atau amend, pull update, serta mengedit tag, semuanya dengan satu shortcut
Namun sepertinya di sini saya minoritas. Apalagi kalau mempertimbangkan suasana bahwa Git adalah keterampilan wajib dan programmer sejati harus bisa mengetik perintah sambil memejamkan mata; saya penasaran mengapa begitu
Keterampilan ini tidak bergantung pada lingkungan: saat masuk ke mesin remote dan melihat repository, rasanya sama seperti lokal; tidak perlu mempelajari ulang cara integrasi VCS di setiap editor; dan bisa tetap memakai alat yang sudah akrab
Pekerjaan yang Anda contohkan juga bisa dilakukan sama mudahnya di command line, jadi saya tidak melihat integrasi editor sebagai sesuatu yang istimewa. Kalau perlu operasi aneh dan tingkat lanjut seperti mengutak-atik reflog, kemungkinan besar pada akhirnya tetap harus membuka command line
Tentu saja saya tidak keberatan dengan orang yang memakai GUI. Kalau produktif dengan alat itu, bukan tempat saya untuk menghakimi. Anda bertanya alasannya, jadi saya menjawab; saya tidak mengklaim cara saya lebih baik
Konteks paling umum ketika orang berkata “Anda harus belajar Git CLI” adalah kasus seperti ini
Beberapa hari lalu pun ada contoh yang menyarankan memakai GitHub Desktop agar tidak perlu mempelajari perintah Git: https://www.reddit.com/r/learnprogramming/comments/15b7pra/s...
Berkat pendekatan yang mengedepankan kompatibilitas Git terlebih dahulu, Jujutsu terlihat lebih kuat sebagai kandidat pengganti Git dibanding yang pernah saya lihat sejauh ini
Setelah membaca penjelasan kompatibilitas Git, hal yang membuat saya penasaran adalah sepertinya fokus utamanya pada kasus penggunaan ketika pengguna Jujutsu mengakses repositori Git yang di-host di GitHub dan sejenisnya dengan jj. Sebaliknya, saya juga penasaran apakah cara mengakses repositori native Jujutsu dengan Git juga didukung
Karena sebagian besar developer sudah akrab dengan Git CLI, dalam operasi nyata tampaknya akan ada developer yang memakai jj dan Git bersama-sama pada codebase yang sama. Atau saya penasaran apakah skenario operasional yang realistis adalah selalu memakai Git sebagai repositori backend, bukan database native Jujutsu, demi akses CLI di kedua sisi
Backend ini terutama ada untuk memastikan bahwa di kemudian hari fitur yang tidak mudah ditambahkan ke backend Git dapat dimasukkan
Jika ingin bekerja dan berkontribusi pada proyek yang sudah memakai Jujutsu, masuk akal jika saya yang menyesuaikan diri dengan proyek, bukan proyek yang menyesuaikan dengan alur kerja saya
Berkat pendekatan kompatibilitas Git terlebih dahulu, Jujutsu terlihat lebih kuat dibanding kandidat pengganti Git yang pernah saya lihat sejauh ini
Saya penasaran soal manajemen konflik. Saya tahu pmeunier mencurahkan banyak perhatian untuk memformalkan teori patch demi Pijul, dan konsep patch/konflik yang tidak sound atau bermasalah bisa berujung pada masalah besar. Sepertinya masalah performa Darcs muncul seperti itu
Akan bagus jika halaman perbandingan di wiki repositori menjelaskan penanganan konflik Pijul sedikit lebih detail daripada sekadar “mirip”
Dengan menyimpan konflik secara simbolik seperti ini, konflik bisa direproduksi nanti dan konflik tertentu bahkan dapat diselesaikan otomatis, tetapi ini tidak sampai menangani masalah penyelesaian isi konflik itu sendiri
Jika ada yang mengimplementasikannya, mungkin Pijul sebagai backend jj bisa dipakai untuk mendapatkan keunggulan dari keduanya
Replikasi aman lewat rsync, Dropbox, dan sistem file terdistribusi, bagus sekali. Belakangan saya makin condong ke sistem yang ramah sinkronisasi sederhana
Karena cukup dilempar ke mana saja dengan alat apa saja dan tetap berjalan. Selalu menyenangkan melihat alat baru mengambil arah seperti ini
Saya pernah mendengar adanya masalah seperti ini, tetapi belum pernah mengalaminya langsung. Saya penasaran race condition seperti apa yang muncul antara Git dan alat seperti rsync/Dropbox hingga menyebabkan masalah
Syukurlah, working copy otomatis di-commit. Ini fitur yang sudah lama dibutuhkan
Apresiasi untuk Martin yang telah mencurahkan tenaga membuat alat yang elegan