Commit Git Favorit Saya (2019)
(dhwthompson.com)- Commit “Convert template to US-ASCII to fix error” dari Dan Carley saat mengerjakan GOV.UK menunjukkan bahwa perubahan kode kecil pun bisa menjadi dokumentasi jangka panjang bagi codebase lewat pesan commit yang mendetail
- Pesan yang baik meninggalkan alasan mengapa sesuatu diubah, bukan sekadar apa yang diubah; contoh ini secara spesifik mencatat error
invalid byte sequence in US-ASCIIyang terjadi saat menjalankanbundle exec rakebeserta kondisi reproduksinya - Karena string error dan proses investigasinya ikut tersimpan, orang yang kemudian menemui masalah yang sama bisa menemukan catatan solusi sebelumnya lewat
git log --grepatau pencarian commit GitHub - Pesan tersebut juga mencakup proses penggunaan tool Unix seperti
find -exec,file --mime, daniconv, sehingga reviewer dan pembaca di kemudian hari bisa mengikuti alur pemecahan masalahnya - Tidak semua commit perlu sepanjang ini, tetapi pesan yang menyimpan konteks, proses investigasi, bahkan emosi dapat membantu membangun pemahaman bersama tentang codebase dan kepercayaan dalam tim
Commit yang Mengubah Perubahan Kecil Menjadi Dokumentasi Jangka Panjang
- Jika ditulis dengan baik, pesan commit Git dapat menjadi alat dokumentasi yang kuat yang bertahan sepanjang umur codebase
- Commit yang dijadikan contoh adalah perubahan dari masa pengerjaan GOV.UK di Government Digital Service
- Penulisnya adalah Dan Carley, dan judulnya “Convert template to US-ASCII to fix error”
- Berkat cara pengembangan terbuka GDS, contoh internal organisasi seperti ini juga bisa dibagikan ke luar
Konteks Lebih Penting daripada Panjang
- Commit ini memiliki pesan yang panjang dibandingkan jumlah perubahan kodenya, tetapi nilai utamanya bukan panjang itu sendiri, melainkan konteks yang berguna
- Perubahan yang sama di tempat lain mungkin saja hanya dicatat singkat seperti
change whitespaceataufix bug - Dan meninggalkan catatan mendetail agar rekan di sekitarnya dan pembaca di kemudian hari dapat memahami penyebab masalah dan proses penyelesaiannya
Bukan Hanya Apa yang Berubah, tetapi Mengapa Berubah
- Pesan commit yang baik menjelaskan bukan hanya apa yang berubah, tetapi juga mengapa perubahan itu dilakukan
- Commit ini mencatat bahwa setelah menambahkan test di feature branch untuk mencocokkan isi
/etc/nginx/router_routes.conf, hasilnya berbeda tergantung cara menjalankannya- Jika dijalankan dengan
bundle exec rake specataubundle exec rspec modules/router/spec, semuanya berjalan normal - Jika dijalankan dengan
bundle exec rake, setiap blokshouldgagal - Error-nya adalah
ArgumentError: invalid byte sequence in US-ASCII
- Jika dijalankan dengan
- Tanpa penjelasan seperti ini, besar kemungkinan orang harus menebak tool mana yang memunculkan error parsing apa
- Konteks pekerjaan asli mudah hilang ketika orang lupa, pindah tim, atau meninggalkan organisasi
Catatan Error yang Bisa Dicari
- Di bagian awal pesan commit, pesan error yang memicu perubahan dimasukkan apa adanya
- Orang yang menemui error yang sama dapat menemukan catatan sebelumnya di codebase dengan cara berikut
git log --grep "invalid byte sequence"- GitHub commit search
- Dari hasil pencarian, terlihat bahwa beberapa orang telah mencari error ini, dan juga dapat diketahui siapa yang lebih dulu menemui masalah tersebut serta tindakan apa yang dilakukan
Meninggalkan Proses Pemecahan Masalah sebagai Cerita
- Pesan tersebut disusun agar pembaca bisa mengikuti bagaimana masalah terlihat, urutan investigasinya, dan bagaimana akhirnya diperbaiki
- Sebagai contoh, isinya mencakup bahwa error hilang ketika matcher
.with_content(//)dihapus, tidak ada karakter aneh di file spec, dan masalah dapat direproduksi ketika me-require Puppet dari interpreter yang sama - Karena pesan commit mendokumentasikan perubahan itu sendiri, bukan file, fungsi, atau satu baris kode tertentu, commit adalah tempat yang baik untuk merekam perjalanan yang telah dilalui codebase
Efek Samping: Memperluas Pengetahuan Tim
- Dan mencatat perintah yang ia jalankan di setiap tahap investigasi, dan ini bisa menjadi cara ringan untuk menyebarkan pengetahuan di dalam tim
- Dari pesan commit saja, pembaca dapat mempelajari penggunaan tool Unix
- Dengan meneruskan argumen
-execkefind, kita bisa menjalankan perintah pada setiap file yang ditemukan - Jika menambahkan
\+di akhir perintah, alih-alih menjalankannya sekali untuk setiap file, beberapa nama file diteruskan ke satu perintahfile file --mimememberi tahu tipe MIME sebuah file- Ada tool bernama
iconv
- Dengan meneruskan argumen
- Bukan hanya orang yang me-review perubahan, tetapi juga orang yang menemukan commit ini di kemudian hari akan memperoleh informasi yang sama
- Seiring cukupnya waktu dan bertambahnya commit, pesan seperti ini dapat menjadi perangkat pengganda pengetahuan bagi tim
Catatan yang Membangun Empati dan Kepercayaan
- Di akhir commit ada kalimat “Now the tests work! One hour of my life I won't get back..”
- Kalimat ini menyampaikan frustrasi seorang developer yang melacak bug licik selama satu jam, sekaligus kepuasan saat berhasil menyelesaikannya
- Bahkan ketika hack jangka pendek atau kode prototipe masuk ke production dan berakar di sana, pesan seperti ini mengingatkan bahwa di balik setiap perubahan ada seseorang yang mengambil keputusan terbaik berdasarkan informasi yang tersedia saat itu
Tidak Semua Commit Perlu Panjang
- Contoh ini adalah kasus yang ekstrem, dan terutama untuk commit sebesar ini, tidak perlu mengharapkan tingkat detail yang sama pada semua commit
- Meski begitu, ini adalah contoh baik tentang menjelaskan konteks di balik perubahan, membuat orang lain belajar, dan berkontribusi pada model mental bersama tim terhadap codebase
- Jika tertarik pada pesan commit yang baik dan tool untuk menyusun perubahan, Anda bisa melihat materi berikut
- Telling stories through your commits oleh Joel Chippindale
- A branch in time oleh Tekin Süleyman
1 komentar
Pendapat Hacker News
Baik atau buruk, dari sudut pandang salah satu pendiri GitHub dan penulis buku tentang Git seperti Pro Git, pesan commit Git adalah jalur unik untuk mendokumentasikan kode, tetapi sangat tidak efisien.
Masalah utamanya adalah kebanyakan alat seperti Git dan GitHub biasanya hanya menampilkan baris pertama. Commit contoh pun hanya memperlihatkan satu baris umum seperti “US-ASCII error”, sementara sisa isi yang dipuji dalam tulisan itu nyaris tidak dilihat siapa pun di alat modern.
Git merancang pesan commit sebagai isi email yang dibaca semua orang di proyek, tetapi hari ini umumnya tidak berperan seperti itu. Kecuali dibahas sebagai seri patch di mailing list, hampir tidak ada yang terbaca selain 50 karakter pertama pada judul.
Bahkan ketika di
git blamekita mencari apakah opsinya-w -C -C -Catau dua-Cuntuk melacak pesan terkait, yang terlihat tetap hanya baris pertama, dan pada akhirnya harus menemukan SHA lalu menjalankangit showuntuk melihat pesan panjangnya. Salah satu keluhan terbesar saya terhadap Git adalah bahwa meski ditulis dengan baik, informasinya terlalu sulit ditemukan kembali.Jika melihat riwayat proyek Git, pesan commit-nya hampir selalu luar biasa, tetapi meski menjalankan
blamepada satu file, sangat sulit mengikuti konteks implementasi sebuah fungsi. Dokumentasi yang ditinggalkan Jeff King selama 10 tahun terakhir berada pada level jenius, tetapi mengerikan bahwa hampir tidak ada orang yang bisa mengapresiasinya.Saya tidak tahu solusi tepatnya, tetapi di sebagian besar komunitas, menulis dokumentasi hebat dalam pesan commit sayangnya hampir seperti membuang waktu. Karena terlalu sulit ditemukan.
git blame,git log, dangit show; mengikuti riwayat file itu mudah, dan dengangit log -Ghanya butuh beberapa detik untuk menemukan kapan sesuatu ditambahkan atau dihapus.Yang menyulitkan adalah ketika commit sudah ditemukan tetapi pesannya hanya “bleh” atau “add a thing”. Padahal pengembang cukup meluangkan 60 detik untuk menulis kenapa mereka melakukannya.
Sebaliknya, menemukan pesan commit yang menjelaskan secara rinci mengapa suatu perubahan dilakukan itu benar-benar menyenangkan. Satu pesan commit yang bagus bisa menghemat berjam-jam, bahkan berhari-hari pekerjaan.
GitHub juga ikut menyumbang masalah pesan commit yang buruk. Kalau beruntung, detailnya ada di deskripsi PR, tetapi tidak berada persis di sebelah log commit; biasanya PR mengarah ke tautan Jira, Jira ke tautan percakapan Slack, dan Slack ke tautan dokumen Google.
Industri ini benar-benar buruk dalam dokumentasi, tetapi orang-orang seperti Jeff King sedang memperjuangkannya dengan benar. Pada akhirnya saya melihatnya bukan sebagai masalah teknis, melainkan masalah manusia. Menulis dokumentasi tidak memberi imbalan langsung sehingga terasa seperti pekerjaan tambahan, dan manfaatnya baru muncul beberapa hari, minggu, atau bulan kemudian.
Tolong tulislah pesan commit yang baik. Cukup luangkan 1 menit untuk menulis mengapa itu dilakukan, maka tidak setiap commit menjadi teka-teki pagar Chesterton sialan. Jika ditaruh dalam pesan commit yang mudah ditemukan, diri Anda di masa depan dan saya akan berterima kasih.
Tambahan lagi, saya juga tidak setuju dengan klaim bahwa pesan commit sulit ditemukan. Saya hampir tidak merasa kesulitan mengikuti sejarah satu baris kode, fungsi, atau file, dan meski pesan commit tidak dibaca ulang, pesan itu tetap bernilai saat ditulis. Menulis pesan yang baik membuat saya memeriksa apakah saya benar-benar menulis kode yang saya maksudkan, dan juga bernilai bagi reviewer kode.
Pernyataan bahwa opsi
git blamesulit ditemukan juga terdengar seperti lelucon. IDE yang baik menempelkan informasi blame pada setiap baris dan menampilkan diff dengan satu tombol, lalu dari diff itu seharusnya bisa melakukan blame secara rekursif pada baris konteks atau baris yang dihapus. Alat seperti Tig melakukan persis itu.Saya mengakui GitHub memang membuat pesan commit sulit dilihat.
Dokumentasi yang melekat pada commit bukan ditulis untuk iseng. Itu adalah mekanisme untuk mengurangi risiko menerima patch dari seseorang yang mungkin tidak ada lagi nanti, serta mengungkap pemikiran terkait agar orang lain bisa bekerja di atasnya. Jika pemikiran disembunyikan, kepemilikan eksklusif atas kode akan menumpuk, dan biasanya itu bukan hal baik. Pesan commit juga berfungsi sebagai bukti kerja, dan bisa menjadi penting ketika patch terlalu banyak. Dalam proyek komersial, sebagian kepentingannya mungkin lebih rendah.
Sebenarnya tidak ada tempat lain yang cocok untuk menaruh dokumentasi seperti ini. Komentar kode tidak pas. Namun sekarang ada generasi pengembang yang berpikir Git sama dengan GitHub, dan satu-satunya tujuan Git adalah mengunggah perubahan ke GitHub.
Git memang buruk, tetapi jauh tidak seburuk hal-hal lain. Kita perlu kembali ke dasar dan memahami tujuan sebenarnya dari version control.
Jadi mungkin tidak banyak membantu komunitas saat ini, tetapi akan membantu orang yang melakukan debugging beberapa tahun kemudian
Saya setuju dengan maksud umumnya, tetapi akan lebih baik jika menaruh BLUF yang lebih spesifik di depan. Misalnya menulis “Fix test issues caused by non-breaking space character \xa0”
Masalahnya langsung bisa dipahami, dan kalau ingin tahu lebih lanjut, pembaca tetap bebas membaca bagian di bawahnya
Jadi untuk pencarian riwayat, pesan baris pertama yang baik saja sudah cukup. Cerita pendek tentang pergi sampai ke Narnia untuk mencari akar penyebab bug lalu kembali lagi menurut saya tidak terlalu relevan. Namun saya tidak menentang kalau itu ditulis sebagai pelampiasan di deskripsi PR atau pesan lanjutan commit
Saya pernah merasakan kebanggaan saat menulis pesan commit yang bagus, tetapi saya kurang yakin dengan nilainya bagi orang lain. Saat menemukan pesan error aneh, menambahkan fitur baru, atau hampir dalam situasi apa pun, menurut saya kebanyakan orang tidak mencari lewat pesan commit
Agak menyedihkan, tetapi saya makin curiga bahwa pesan commit yang indah punya sisi yang dekat dengan kesombongan programmer. Yang paling sering mengaguminya adalah penulisnya sendiri, sementara orang lain berlalu tanpa menyadarinya
Kadang ada ruang untuk hiasan estetis semacam itu, tetapi saya tidak yakin nilai praktisnya besar. Sekarang saya tidak terlalu peduli lagi kalau orang lain menulis commit “fix whitespace issue”, dan rasanya itu membuat saya menjadi rekan kerja yang lebih baik
Mungkin berbeda untuk proyek seperti Git atau Linux, dengan tim terdistribusi yang sangat besar dan jumlah commit yang sangat banyak. Proyek-proyek yang saya kenal biasanya memiliki 1–100 kontributor dan kebanyakan berada dalam organisasi yang sama
Saat tidak menemukan jawaban di Google atau Stack Overflow, saya juga mencari di GitHub apakah ada hal serupa di PR atau pesan commit. Termasuk repositori privat yang bisa saya akses, itu sudah tak terhitung seringnya membantu. Pesan commit yang baik jelas punya nilai melampaui kesombongan. Kalau banyak developer tidak melihatnya, itu kerugian mereka sendiri, dan semoga mereka menyadarinya suatu hari saat pengalaman bertambah. Mengajari developer junior cara mencari, atau mengirim artikel aslinya, juga bagus
Sejak itu saya berusaha menulis pesan commit setidaknya agar diri saya di masa depan bisa mengingat mengapa perubahan itu diperlukan
git blame, berarti Anda melakukannya dengan keliruBeberapa kali, saat hendak memperbaiki bug yang tampak jelas, tepat sebelum commit saya melihat commit sebelumnya dan menemukan bahwa “bug” itu dimasukkan secara sengaja, dan tiket JIRA yang terhubung menjelaskan dengan baik mengapa perubahan saya yang tampak jelas itu akan memunculkan kembali bug dari dua tahun lalu
git blamedi IDE. Saat menemukan pesan commit yang bagus, saya merasa berterima kasihBaris pertama pesan commit adalah yang paling penting karena memungkinkan
git logmenangani pagar Chesterton. Dalam kasus ini, menurut saya penulisnya melesetIntinya, baris pertama harus berisi mengapa hal itu dilakukan, bukan apa yang dilakukan. Apa yang berubah bisa dilihat oleh orang yang tertarik melalui kode atau diff
Misalnya tulis “nginx .conf files must be in us-ascii”, lalu setelah itu “changed blahblah.erb to remove nonbreaking space character”, kemudian lanjutkan dengan sisa pesan commit yang cukup bagus itu
Anggap saja seperti artikel berita. Asumsikan pembaca boleh berhenti membaca di titik mana pun, dan tulislah dengan urutan pentingnya makin menurun sementara detailnya makin bertambah
Artikel berita pun menjelaskan apa, bukan mengapa, di judulnya
Dalam kasus ini, baris pertama teks asli sudah tepat. Saat menelusuri
git log, kita bisa menganggap commit ini kemungkinan besar tidak mengubah perilaku fungsional pengujian, lalu melewatinya“nginx .conf files must be in us-ascii” bisa bagus sebagai judul bug atau PR, tetapi bisa berkaitan dengan beberapa commit yang melakukan hal berbeda-beda, dan tidak memberi tahu apa yang sebenarnya terjadi. Tidak jelas apakah file dikonversi ke US-ASCII, dibuat alat konversi, dokumentasi diperbarui, tes dibuat, atau kombinasi dari semuanya. Memulai dengan apa, bukan mengapa, mengurangi kebingungan itu
Entah “The files must be in us-ascii” atau “Changed the files to us-ascii”, tidak terlalu masalah. Keduanya jelas memberi tahu bahwa file diubah menjadi US-ASCII
Kekurangan dari cara dokumentasi seperti ini adalah pesan commit yang sudah ditulis pada dasarnya tidak bisa diubah
Tentu saja bisa dilakukan dengan
rebase, tetapi apakah kita benar-benar mau mengubah sesuatu yang ditulis setahun lalu dan sudah di-merge kemain, lalu menyusahkan feature branch semua orang?Dibandingkan dengan dokumen yang disimpan di file
.md, Wiki, atau Confluence, saya bisa memperbaiki tulisan rekan kerja, dan rekan lain juga bisa memperbaiki tulisan sayaDalam kasus ini, bug-nya mungkin sudah diperbaiki dan tidak akan muncul lagi. Namun ada godaan untuk menjelaskan desain suatu komponen saat melakukan commit atas komponen itu, dan sekarang saya menghindarinya. Bagaimana jika komponen itu berubah di kemudian hari karena perubahan kebutuhan bisnis dan sebagainya? Apakah dokumentasi commit hanya akan menjelaskan perbedaannya? Kalau begitu, anggota tim baru harus membaca beberapa pesan commit dan menggabungkannya di kepala untuk memahami sistem
Membandingkannya dengan file
.md, Wiki, atau Confluence itu seperti membandingkan sepeda dengan angsaPertimbangan dan kompromi saat komponen dibuat, atau fakta bahwa hal-hal itu tidak ada, sering berguna untuk memahami cacat awal, evolusi berikutnya, dan cacat yang muncul dari perubahan use case
Kalau anggota tim baru perlu memahami sistem, cukup pelihara dokumen “saat ini” yang terpisah. Dokumen itu tidak perlu membahas kompromi implementasi atau fakta bahwa drafnya ditulis di bawah tekanan waktu
Jika commit di-squash, catatannya menjadi lebih baik sebagai cerita penambahan fitur; merge mempertahankan log tak berubah dari perubahan kode yang sebenarnya; rebase melakukan sedikit dari keduanya
Tidak ada alasan kita tidak bisa memiliki keduanya. Kita ini orang yang memprogram komputer, jadi bisa membuatnya sesuai keinginan
Kalau saya menulis ulang Git dari awal, saya akan membagi commit menjadi dua bagian. Riwayat perubahan tetap dibuat tak berubah seperti Git, dengan struktur semacam Merkle DAG, sementara pesan commit disimpan di penyimpanan data terkait yang terpisah agar menjadi log alur kerja yang masuk akal dan dapat diedit. Commit bisa dikelompokkan berdasarkan tag fitur, typo bisa diperbaiki, pesan bisa diubah sesuka hati, tetapi log diff di bawahnya, yaitu “apa yang benar-benar berubah dalam kode”, tetap dipertahankan
git notes. Namun kalau pesannya sepanjang itu, kecil kemungkinan ada orang yang menyadarinyaAda satu bagian yang tidak saya setujui: bagian yang mengatakan “saya tidak mengharapkan tingkat detail seperti ini untuk setiap commit, terutama commit sebesar ini”
Berdasarkan pengalaman, justru hal-hal kecil yang tampak tidak berbahaya sering kali membutuhkan penjelasan yang relatif lebih panjang
Kemarin saya menulis tiga paragraf tentang alasan menambahkan
--limit=999kegh pr list. Karena itu membingungkan. Di dalam argumen--jqjuga sudah adalimit(, dan jika dianggap ada PR tak terbatas, makin tinggi nilainya, hasil akhirnya justru makin rendahSaya juga menulis komentar kode, dan mungkin saya menghabiskan lebih banyak waktu untuk berpikir dan merapikannya daripada untuk menulis. Saya harap ini diingat sebagai contoh berikutnya ketika seseorang menyiratkan bahwa pekerjaan ini hanya soal memproduksi kode secara asal-asalan
“This was a non-ascii whitespace character that caused
ArgumentError: invalid byte sequence in US-ASCIIwhen runningbundle exec rake” saja sudah cukup. Ada kata kunci untuk mencari masalah serupa nanti, memuat akar penyebabnya, dan tidak terlalu panjang sehingga kecil kemungkinan orang melewatkannya begitu sajaMenurut saya itu bukan commit Git yang hebat
Dibandingkan teks sebanyak itu, baris pertama “Convert template to US-ASCII to fix error” bisa dibuat lebih baik. Cukup tambahkan beberapa kata tentang karakter spasi mana yang menyebabkan error dan error apa yang terjadi. Dengan penjelasan itu dan diff-nya, konteks yang diperlukan sudah cukup
Sejujurnya, sisanya hampir tidak berguna. Tidak merugikan, tetapi nilainya juga tidak besar. Penulis mendokumentasikan perjalanan melacak bug ini, tapi siapa yang peduli?
Artikel itu juga memiliki tautan hasil pencarian yang menunjukkan beberapa commit dari orang-orang yang belajar dari perbaikan tersebut
Pesan commit itu adalah gudang pengetahuan
Kalau ingin melihat pesan commit yang bagus, lihat riwayat Git kernel Linux. Di sana ini adalah standar
Baris pertama selalu menyebut subsistem yang terdampak perubahan, lalu diikuti ringkasan satu baris dalam bentuk imperatif. Setelah itu, jawab tiga pertanyaan sedetail mungkin
Contohnya bisa ditulis seperti “Kode saat ini melakukan X. Saat menjalankan test case T, perilaku tak terduga U teramati. Ini terjadi karena alasan R. Perbaiki dengan melakukan F”
Baru-baru ini seorang kontributor mengatakan kepada saya bahwa pendekatan saya terhadap pesan Git, yaitu persyaratannya, “unik”. Sepertinya latar belakang kernel Linux saya terlihat, tetapi semua pesan commit saya memang terlihat seperti yang dijelaskan di sini
Jika isinya tentang kode yang ada, komentarnya harus berada bersama kode. Hal-hal terkait proses, misalnya kode yang dihapus atau kode yang dulu tidak berfungsi, harus ada di commit
Yang paling penting adalah pesan commit boleh merujuk ke issue demi kemudahan, tetapi detail inti harus direproduksi. GitHub bersifat sementara, tetapi pesan Git tidak
Pesan commit yang penuh konteks ada di sini[1]
Hal seperti ini sangat sering terjadi sampai-sampai maintainer menulis artikel ini[2]
[1] https://github.com/git/git/commit/d70f554cdf38b0b05cfaa8e8eb...
[2] https://lore.kernel.org/git/xmqqedevo8ps.fsf@gitster.g/