Distributed Version Control System

Wah udah lama saya ngga mengisi blog ini. Saya akan awali lagi mengisi blog ini dengan cerita sedikit mengenai pengalaman saya menggunakan distributed version control system alias DVCS.

Dari sekian DVCS yang ada, saya cuma pernah memakai Bazaar, Git, dan terakhir Mercurial. Saya bisa dibilang sudah meninggalkan Bazaar, yang saya kenal sambil mengembangkan BlankOn, setelah saya mengenal Git. Sejak sekitar dua tahun lalu, saya mencoba menggunakan Mercurial. Sebelum saya menggunakan Bazaar, saya biasanya menggunakan Subversion.

Yang sekarang bisa saya simpulkan mengenai pengalaman saya menggunakan ketiga DVCS ini adalah seperti berikut.

  • Perpindahan dari Subversion ke Bazaar tidak terlalu sulit bagi saya. Saat itu saya hanya perlu tahu konsep repositori lokal, yang secara praktis berarti harus memahami bahwa commit itu hanya akan menyimpan perubahan ke repositori lokal dan push itu dibutuhkan agar perubahan dikirim ke repositori bersama.
  • Saya juga belajar bahwa repositori lokal ini dapat disalin ke direktori lain dan secara otomatis kita akan memiliki sebuah cabang repositori baru.
  • Saat mencoba2 Git, saya menemukan sebuah konsep baru yaitu staging area. Operasi commit pada Git itu hanya akan menyimpan perubahan yang sudah dimasukkan ke dalam staging area. Karena saya masih baru menggunakan Git, perintah git commit -a, yang berarti add dan commit sekaligus, adalah perintah yang saya pakai untuk melakukan commit.
  • Setelah beberapa waktu, saya menemukan operasi commit secara interaktif dengan git commit -i. Saya bisa memilih dulu berkas mana yg ingin saya commit dan mana yg tidak.
  • Selain commit secara interaktif, Git juga memiliki operasi untuk memasukkan berkas ke staging area secara parsial, yang artinya juga kita bisa melakukan commit secara parsial, dengan perintah git add -p. Kita akan dihadapkan dengan pertanyaan bertubi-tubi mengenai setiap perubahan yang kita buat: ingin dimasukkan ke staging area atau tidak.
  • Semakin sering saya menggunakan git add -p semakin paham pula saya apa kegunaan dari staging area dan mengapa ini adalah fitur Git yang sangat powerful yang membedakan Git dengan yang lain
  • Selain ini, saya juga tau bahwa cabang di Git dapat berada di dalam satu buah repositori lokal (alias direktori) yang sama.
  • Setelah saya terbiasa dengan commit parsial, saya mencoba menggunakan Mercurial. Operasi pertama yang saya cari: commit parsial dan pembuatan cabang.
  • Mercurial tidak memiliki staging area sehingga operasi commit akan menyimpan semua perubahan yang dibuat. Sama dengan operasi commit di Bazaar dan bahkan Subversion.
  • Ada pengaya (extension) Mercurial yang dapat membuat kita melakukan commit secara selektif, yaitu Record Extension. Namun walau begitu, ini masih kalah canggih dibanding punyanya Git dalam urusan memilah-milah perubahan.
  • Mercurial memiliki tiga jenis percabangan: cabang dengan nama alias named branch, cabang tanpa nama alias anonymous/unnamed branch, dan bookmark.
  • Cabang dengan nama di Mercurial bersifat permanen: nama cabang akan selalu dibawa ke mana-mana termasuk saat perubahan dikirim ke repositori lain (push).
  • Bookmark adalah jenis cabang di Mercurial yang mirip dengan percabangan di Git.

Kesimpulan lain: Git dapat itu mengubah pikiran dan cara pandang Anda mengenai bagaimana cara menggunakan version control system. Setelah Anda paham mengenai penggunaan Git, maka menggunakan (D)VCS lain itu bisa bikin stres 😛 *kisah nyata*

Cara cepat menyediakan server Mercurial

Langsung aja ke inti masalah..

$ mkdir repo-utama
$ cd repo-utama
$ cat > .hg/hgrc <<EOF
> [web]
> allow_push = *
> push_ssl = false
> EOF
$ hg serve

Selamat! Anda telah memiliki sebuah server Mercurial! Server ini bisa diakses di http://ip-kompi-tersebut:8080/

Berhubung sangat sederhana, server ini tidak butuh otentikasi apa2 sehingga semua orang bisa melakukan push ke sana. Jadi hati-hati juga!

Mari kita salin, tambahkan isinya, dan push kembali.

$ hg clone http://localhost:8000/ salinan
$ cd salinan
$ touch ini itu
$ hg add ini itu
$ hg commit -m 'tambah ini itu'
$ hg push http://localhost:8000/

Selesai!

Backup data dg DVCS

Sejak bbrp hari yang lalu saya nyari2 cara tuk membackup data (er.. foto sih tepatnya =D) dg mudah di harddisk eksternal. Berhubung saya jg pengen ada fasilitas versioning, cara backup dg rsync tidak bisa diambil mentah2.

Aplikasi selanjutnya yg terpikir adalah Time Machine yg ada di Mac OS X. Namun setelah baca2, Time Machine tidak bisa melakukan backup secara selektif dalam artian hanya direktori yg dipilih saya yang dibackup, akhirnya Time Machine juga tidak jadi dipilih. Time Machine hanya bisa diatur untuk mengecualikan direktori yg dipilih dan bukan sebaliknya. Kalau begini kondisinya, sudah tentu harddisk eksternal saya akan cepat penuh berhubung Time Machine akan melakukan backup sistem secara keseluruhan.

Sempat mikir juga tuk menggunakan DVCS seperti Git. Namun sejak ingat Git dan DVCS lain akan menduplikasi data yg ada di harddisk internal ke dalam repositori lokalnya juga, pemborosan harddisk akan tetap terjadi. Walau Git melakukan kompresi data, tapi untuk data binari seperti foto rasanya tidak akan begitu berpengaruh. Jadi kalau kita punya foto sebanyak 10GB, maka Git akan menyalinnya ke repositori lokal sehingga total data yg kita simpan bisa mencapai 20GB. Saya jadi ragu tuk menggunakan DVCS tuk membackup data foto.

Loh kok jadi kontradiksi dengan judul?

Tidak, karena tulisan ini belum selesai =P Kekhawatiran tadi akhirnya bisa diakalin sehingga tidak akan terjadi duplikasi data pada harddisk yg sama. Harddisk internet dan eksternal masing-masing akan menyimpan 1 salinan data saja, jadi sangat efisien. Bagaimana caranya?

Caranya adalah dengan meletakkan repositori lokal yang seharusnya ada pada harddisk internal ke harddisk eksternal!

Agar repositori lokal tersebut tetap bisa diakses dari harddisk internal, sebuah symlink digunakan untuk menunjuk direktori repositori lokal yg ada di harddisk eksternal tersebut. Teknik menggunakan symlink ini belum tentu bisa digunakan di seluruh DVCS. Saya sudah mencoba dengan Git dan Bzr dan ternyata keduanya bisa melakukan seluruh skenario yg saya inginkan butuhkan, yang akan saya tunjukkan berikut ini.

Katakanlah direktori yg ingin dibackup adalah ~/Foto/ dan harddisk eksternal ada di /eksternal/

  1. Menginisialisasi repositori

    $ cd Foto
    $ git init
    $ mv .git /eksternal/Foto.git
    $ ln -s /eksternal/Foto.git .git
    
  2. Backup data yang ada

    $ git add .
    $ git commit -a -m "backup"
    

    Proses ini bisa saja dilakukan secara terjadwal. Jangan lupa mengecek dulu apakah harddisk external tsb sedang dipasang atau tidak.

  3. Mengembalikan data dari direktori backup.

     $ mkdir FotoBaru
     $ cd FotoBaru
     $ ln -s /eksternal/Foto.git .git
     $ git checkout HEAD -- .
    

    Selain pake cara di atas, bisa jg lgs git clone direktori /eksternal/Foto.git namun direktori baru yg terbentuk akan membengkak 2x lipat karena berisi repositori lokal dan juga salinan lokal.

    Jika menggunakan Bzr, perintah terakhir diganti menjadi bzr revert

  4. Mengembalikan file tertentu dari sebuah revisi tertentu.

     $ git checkout [revisi] -- [nama/file]
    

    jika menggunakan Bzr, maka perintah di atas menjadi seperti berikut.

     $ bzr revert -r[revisi] [nama/file]
    

Kira-kira seperti itu saja =D ada yang mau mencoba dg DVCS lainnya?

Oh ya.. direktori backup yang ada di harddisk eksternal tidak bisa dibuka begitu saja dengan untuk melihat data-data didalamnya karena data tersimpan dalam format repositori DVCS yang digunakan. Untuk melihatnya tentu saja harus dikembalikan dulu ke salinan lokal dg aplikasi DVCS yang digunakan. Cara ini memang sepertinya hanya ditujukan bagi yang ingin menjadikan harddisk eksternal tsb hanya sebagai tempat backup, bukan tempat berbagi data jg dg orang lain. Asumsinya kalau untuk berbagi data, maka isi harddisk dapat dilihat scr langsung tanpa bantuan aplikasi backup yg dipakai.

GitHub emang keren

Sepertinya saya benar-benar hanya akan menggunakan GitHub untuk menampung seluruh proyek iseng-iseng saya. Rasanya memang benar http://whygitisbetterthanx.com/ menuliskan GitHub sebagai salah satu alasan mengapa Git itu lebih baik =D

Selain GitHub, saya juga punya bbrp proyek di Google Code (misalnya Daluang) dan di Launchpad (misalnya Sedot). Awalnya saya memakai Google Code karena, kalau tidak salah, saat itu public source code hosting tuk open source project yang enak dan mudah dipakai itu hanya Google Code. SourceForge itu terlalu ribet, terlalu bertele-tele, dan terlalu besar. Namun ada satu hal yang tidak saya sukai dari Google Code, yaitu karena hanya mendukung Subversion sedangkan saya sudah mulai meninggalkan centralized version control system seperti Subversion. Yaya.. baru-baru ini Google Code juga mendukung Mercurial jadi mungkin saya akan meliriknya kembali.

Lalu.. Launchpad. Salah satu alasan saya tuk memakainya adalah karena Bazaar dan mungkin Karma hehehe.. Yang kurang enak dari Launchpad adalah perjalanan dari halaman muka proyek ke peramban kode sumber yang terlalu ribet. Selain itu, tidak ada Wiki! jadi susah kalau mau nulis macem2. Terlepas dari hal-hal ini, Launchpad sudah cukup nyaman dipakai.

Awalnya saya juga kurang puas dengan GitHub karena GitHub tidak memiliki fasilitas ticketing. Namun, baru-baru ini akhirnya GitHub memiliki fasilitas ini! Komplit sudah apa yang kira-kira saya butuhkan. Selain itu, ternyata github juga punya hal lain yg tidak kalah keren, yaitu GitHub Pages yang memungkinkan kita tuk membuat halaman web untuk proyek yg kita punya, walaupun hanya dalam bentuk berkas HTML murni saja. Sebenernya saya masih agak-agak kurang sreg dengan cara yg dipakai untuk meletakkan berkas-berkas HTML ini, yaitu dg membuat sebuah cabang khusus. Saya agak-agak merasa bahwa cabang ini kok rasanya tidak cocok tuk menjadi bagian dari repositori proyek. Tapi hal ini bisa sangat diperdebatkan.

Jadi intinya, pakailah distributed vcs =P

Oya, mengapa saya tiba2 nulis ini? karena saya baru aja memakai fasilitas GitHub Pages ini.. hehhe.. silakan cek http://fajran.github.com/luaspot/.

Git Philosophy

Dari Advanced Git Tutorial by Sarah Sharp.

Git Philosophy

  • Commit early, commit often.

  • One commit represents one idea or one change.

    • Makes it easy to read patches
    • Easy to revert unwanted changes later
  • Your working directory, index, and local repo are your scratch pads.

Saya sangat setuju dengan seluruh hal di atas =D Sesuatu yang tidak bisa susah dilakukan andai menggunakan centralized vcs.

Yang asik dari …

Beberapa hal dari VCS alias Version Control System yang saya rasa lebih asik daripada VCS yang lain (tentu saja yg pernah saya pakai). Hal-hal menarik yg saya tuliskan di sini adalah hal-hal yang sudah saya pakai. Tentu saja masih banyak hal menarik yg belum saya temukan/rasakan. Silakan ditambahkan kalau mau..

Git

  1. Github
  2. Bikin cabang di tempat yang sama! Jadi ngga perlu ganti2 direktori kalau mau bikin/gabung cabang (ref: git branch).
  3. Tidak perlu pusing mikirin perubahan nama berkas. Perubahan nama berkas secara otomatis tercatat.
  4. Bisa nyomot perubahan dalam sebuah commit pada sebuah cabang untuk diterapkan pada cabang yang lain (ref: git cherry-pick).

Daftar akan terus bertambah xD

Bazaar

  1. Launchpad

Duh.. gak kok gak bisa nemuin yang lain =))

Yang pasti, pada dasarnya Distributed VCS >> Centralized VCS.

Subversion

  1. Google Code Hosting
  2. Repositori “parsial”. Direktori apa saja bisa jadi root directory dari sebuah repositori Subversion.

Itu aja kayanya. Saya bukan penggemar VCS yang terpusat lagi =D

Mengapa Distributed Version Control System itu lebih enak dipake

Menurut saya, karena bisa commit dan cabang sesuka hati tanpa harus “mengganggu” orang! Kalau sudah dirasa puas, baru deh di-push ke repositori bersama.

Contoh kasus:

Andai saya sedang mengerjakan suatu fitur. Proses pengerjaan sangat mungkin melibatkan berbagai eksperimen pendahuluan sebelum benar-benar menulis kode yang akan membentuk fitur yang kita kerjakan. Eksperimen yang saya maksud ini contohnya adalah potongan kode-kode pendek yang hanya berupa proof of concept. Berawal dari proof of concept inilah baru kita menyusun kode sebenarnya yang nantinya akan kita simpan di repositori utama (okeh, ini memang agak-agak membuat hal terdistribusi menjadi terpusat).

Selain berbentuk proof of concept, eksperimen dapat juga berbentuk beberapa alternatif cara pembuatan fitur. Setelah kita mencoba beberapa alternatif yang ada, salah satu akan dipilih sebagai kode yang benar-benar menjadi fitur yang dikerjakan.

Dalam pembuatan alternatif maupun proof of concept sangat mungkin kita perlu menyimpan apa yang sudah kita buat. Agar seluruh perubahan dapat ditelusuri, maka tentunya akan lebih baik jika perubahan tersebut kita simpan dalam Version Control System (VCS) yang kita pakai.

Jika kita menggunakan VCS yang terpusat, seluruh kode eksperimen kita ini akan tersimpan dalam repositori utama. Sesuatu yang menurut saya bisa “mengganggu” orang lain atau membuat “sampah” pada repositori utama tersebut. Cabang dapat dibuat dan dihapus dari repositori tersebut namun tetap saja seluruh perubahan akan tersimpan. Padahal, mungkin sebenarnya hanya kode versi final yang perlu disimpan.

Sedangkan kalau kita tidak ingin “mengotori” repositori utama, kita akan cenderung untuk tidak menyimpannya dalam VCS. Proses penyimpanan/backup/penelusuran akan dilakukan secara manual. Lalu, apa gunanya VCS?

Jika kita menggunakan VCS yang terdistribusi, kode-kode eksperimen ini dapat disimpan dengan nyaman pada cabang lokal yang kita miliki. Setelah kita punya satu versi yang dirasa cukup layak untuk dijadikan versi final, kita bisa mengirimnya ke repositori utama. “Bersih” bukan?