4 poin oleh GN⁺ 2023-08-02 | 2 komentar | Bagikan ke WhatsApp
  • 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 describe untuk mengedit pesan commit apa pun, jj diffedit untuk mengedit perubahan commit tanpa checkout, jj split untuk membagi commit, dan jj squash -i --from X --into Y untuk 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
  • jj adalah 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

 
xguru 2023-08-03

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.

 
GN⁺ 2023-08-02
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 jj cukup saya sukai
    Waktu 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 log sangat 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, di jj log kita bisa melihat changeset yang akan di-rebase lalu menjalankan jj rebase -s qr -d master, yang lebih cepat daripada mengetik seluruh nama branch

    • Saya penasaran apa yang terjadi kalau tidak sengaja menyimpan file berisi nilai rahasia lalu otomatis ikut tersedot masuk
    • Saya penasaran apakah ini cukup dipakai bersama repositori GitHub biasa
      Tertulis 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
    • Saya penasaran apakah ada contoh tim yang berhasil memakainya. Ingin tahu seperti apa rasanya jika dua orang bekerja di branch yang sama
  • 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...

    • Proyek pribadi bisa menjadi proyek penuh waktu di Google, rasanya pasti cukup membanggakan
  • 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; dengan jj split, commit bisa dipecah; dan dengan jj rebase, commit bisa dipindahkan. Karena semuanya berada di dalam riwayat commit tanpa working tree atau index, semuanya bisa ditangani dengan perintah dan flag yang sama
    Log 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 manual
    Hal 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 nama

  • Saya 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

    • Sebaiknya lihat Pijul. Hampir semua yang disebutkan di sini pada dasarnya sudah diimplementasikan. Pijul berjalan di atas patch yang merupakan CRDT, dan memperlakukan konflik sebagai konsep kelas satu
    • Saya penasaran apakah Anda belum pernah merasakan nilai dari git bisect
      Jika 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 bisect bekerja 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 banyak
      Saya penasaran bagaimana fungsi yang setara dengan git bisect bisa 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 bawah
    • Saya penasaran bagaimana ini akan berkembang dalam praktik
      Ini 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-commit
    Selain itu, jauh lebih mudah men-stage hanya sebagian file lalu commit daripada memecah commit belakangan

    • Menurut saya proyek ini menantang anggapan umum bahwa men-stage hanya sebagian file lalu commit lebih mudah 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 juga berpikir begitu. Biasanya di direktori proyek ada lebih dari 10 file tambahan seperti file output, catatan, atau skrip sekali pakai. Saat memasukkan file ke commit, saya selalu memilih berdasarkan nama file, bukan memasukkan semua yang baru muncul atau berubah
      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.gitignore yang ditambahkan di atas .gitignore. File ignore yang hanya saya butuhkan sangat umum dan bukan sesuatu yang pantas masuk ke .gitignore proyek. Ada caranya, tetapi semuanya terasa canggung, jadi semestinya disediakan secara sederhana secara default
    • Untuk masalah pertama, rasanya cukup dengan mudah membandingkan file yang sudah dilacak dan file baru
      Meski 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
    • Dari sekadar membaca README, saya memahami strukturnya seperti ini: jika file seperti itu ditambahkan ke .gitignore, pada auto-commit berikutnya file tersebut akan dikeluarkan lagi dari commit salinan kerja anonim
      Alur 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
    • Saya kurang mengerti mengapa hal-hal seperti ini menjadi masalah dalam desain jj, dan juga kurang paham mengapa men-stage sebagian file lebih mudah daripada memecah commit belakangan
      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

    • Saya selalu lebih suka menangani sistem version control lewat command line, dan akan terus 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
    • Berdasarkan pengalaman saya, integrasi IDE biasanya tidak mengimplementasikan seluruh kemampuan Git CLI. Mungkin sekarang sudah lebih baik, tetapi begitu melampaui clone/branch/commit/merge dasar dan jumlah developer serta branch sedikit bertambah, pada akhirnya untuk memecahkan masalah tetap kembali ke Git CLI
    • Entah apakah saya programmer sejati, tetapi saya punya ketakutan irasional bahwa Git GUI mungkin melakukan hal yang salah. Di IntelliJ pun saya menangani Git dengan membuka CLI bawaan. Kebiasaan lama sulit hilang
    • Banyak orang yang baru mulai memakai Git tidak memahami cara kerja Git, yaitu apa itu commit dan branch serta apa yang bisa dilakukan dengannya. Lalu mereka menyalahkan alat CLI dan berharap jika memakai GitHub Desktop semuanya akan menjadi jelas
      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...
    • Di tim, hanya ada dua jenis orang yang memahami Git: orang yang memakai CLI, dan orang yang mulai menekan tombol tanpa memahami Git
  • 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

    • Menurut catatan kaki README, saat ini hampir tidak ada alasan praktis untuk memakai backend native
      Backend ini terutama ada untuk memastikan bahwa di kemudian hari fitur yang tidak mudah ditambahkan ke backend Git dapat dimasukkan
    • Sepertinya ekspektasinya adalah selalu memakai Jujutsu sebagai frontend untuk repositori Git, atau memakai repositori remote yang sepenuhnya berbasis Jujutsu
      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”

    • Ada penjelasan yang sedikit lebih detail di sini: https://github.com/martinvonz/jj/blob/main/docs/technical/co...
      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

    • Akan bagus jika ada yang bisa menjelaskan bagian ini lebih lanjut
      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