Pemformatan ulang dan kontrol versi


23

Masalah pemformatan kode. Bahkan lekukan penting . Dan konsistensi lebih penting daripada perbaikan kecil. Tetapi proyek biasanya tidak memiliki panduan gaya yang jelas, lengkap, dapat diverifikasi , dan ditegakkan sejak hari pertama, dan perbaikan besar dapat tiba kapan saja. Mungkin Anda menemukannya

SELECT id, name, address
FROM persons JOIN addresses ON persons.id = addresses.person_id;

bisa lebih baik ditulis sebagai / lebih baik ditulis daripada

SELECT persons.id,
       persons.name,
       addresses.address
  FROM persons
  JOIN addresses ON persons.id = addresses.person_id;

saat bekerja untuk menambahkan lebih banyak kolom ke kueri. Mungkin ini adalah yang paling kompleks dari keempat kueri dalam kode Anda, atau kueri sepele di antara ribuan. Tidak peduli betapa sulitnya transisi, Anda memutuskan itu layak. Tetapi bagaimana Anda melacak perubahan kode di seluruh perubahan pemformatan utama? Anda bisa menyerah dan mengatakan "ini adalah titik di mana kita mulai lagi", atau Anda bisa memformat ulang semua kueri di seluruh riwayat penyimpanan.

Jika Anda menggunakan sistem kontrol versi terdistribusi seperti Git, Anda dapat kembali ke komit pertama, dan memformat jalan dari sana ke kondisi saat ini. Tapi itu banyak pekerjaan, dan semua orang harus berhenti bekerja (atau bersiaplah untuk ibu dari semua penggabungan) saat sedang berlangsung. Apakah ada cara yang lebih baik untuk mengubah riwayat yang memberikan yang terbaik dari semua hasil:

  • Gaya yang sama di semua komit
  • Pekerjaan penggabungan minimal

?

Untuk memperjelas, ini bukan tentang praktik terbaik saat memulai proyek, tetapi apa yang harus dilakukan ketika refactoring besar telah dianggap sebagai Good Thing ™ tetapi Anda masih menginginkan riwayat yang dapat dilacak? Tidak pernah menulis ulang sejarah itu bagus jika itu satu-satunya cara untuk memastikan bahwa versi Anda selalu bekerja sama, tetapi bagaimana dengan manfaat pengembang dari menulis ulang bersih? Terutama jika Anda memiliki cara (tes, definisi sintaks atau biner yang sama setelah kompilasi) untuk memastikan bahwa versi yang ditulis ulang bekerja dengan cara yang sama persis seperti aslinya?


24
Mengapa Anda ingin menulis ulang sejarah? Itu mengalahkan tujuan kontrol versi. Anda ingin memastikan bahwa aplikasi yang Anda kirim 3 bulan lalu cocok dengan revisi xxxxxx tanpa keraguan sedikit pun. Bahkan memformat ulang sepele tidak dapat diterima.
Simon Bergot

5
Saya ingin berkomentar bahwa saya melakukan ini dengan tag "Reformat. Tidak ada perubahan fungsional"
Rig

3
Pada topik yang tidak terkait, sepertinya Anda menyarankan untuk menulis ulang sejarah Git dengan memformat ulang semua kode. Jangan beri tahu orang, menulis ulang riwayat Git buruk untuk 99,9% kasus. Memformat ulang bukan kasus tepi 0,1%.
Andrew T Finnell

4
Dalam beberapa bahasa (saya sedang melihat ANDA, Python) memformat ulang dapat mengubah fungsi logis dari kode. Anda harus dapat mengurai semua bahasa yang disimpan dalam VCS Anda untuk melacak dan mengabaikan pemformatan ulang dengan aman.
Joris Timmermans

3
Reformat adalah perubahan kode dan harus dilakukan.
David Cowden

Jawaban:


26

Lakukan pemformatan ulang sebagai komitmen terpisah. Ini akan sedikit mengganggu sejarah, dan Anda harus dapat melihat sekilas mana yang melakukan hanya memformat ulang dan yang benar-benar mengubah kode. Itu bisa miring git blamedan serupa, tetapi jika itu menunjuk ke komitmen hanya reformat, itu cukup lurus ke depan untuk mencari perubahan sebelumnya sebelum itu.


Saya telah melihat proyek tergelincir selama berminggu - minggu karena salah satu pengembang berpikir ini adalah ide bagus Jika Anda akan melakukan ini, pahami risiko sebelumnya, dan putuskan dengan tepat seberapa jauh Anda akan pergi dengan pemformatan. Saya pikir mjfgates memiliki jawaban yang tepat.
Johntron

1
Kedengarannya seperti tim yang dimaksud memiliki masalah lebih besar daripada pemformatan kode. Tapi ya, saya tidak menyarankan melakukan ini kecuali Anda harus melakukannya. Jika Anda ingin melakukan pemformatan ulang perubahan, saya masih mengatakan lebih baik melakukannya sebagai komitmen terpisah daripada dicampur dengan perubahan fungsional.
Harald

Ya, banyak masalah: PI hanya ingin mengingatkan pengembang baru bahwa itu tidak sesederhana kedengarannya. Alat pemformatan ulang massal berisiko (terutama jika Anda membuatnya sendiri dengan regex - setidaknya menggunakan AST), dan jika Anda peduli tentang tinjauan kode dan pelacakan bug, itu benar-benar dapat mengacaukan proses Anda. Secara pribadi, saya menulis kode saya agar konsisten dengan gaya setiap file, meskipun saya tidak keberatan meninjau kode ketika beberapa fungsi diformat ulang. Banyak pengembang terpaku pada gaya kode dan mengabaikan masalah yang lebih besar seperti arsitektur, proses, perkakas, dll.
Johntron

Dalam pemrograman, tidak ada yang sesederhana kedengarannya :)
harald

13

Jangan menulis ulang sejarah VCS: itu bertentangan dengan prinsip VCS.

Jangan mencoba mengotomatiskan pemformatan: itu mengobati gejalanya, bukan masalah sebenarnya (= pengembang tidak mengikuti standar pengkodean).

Tetapkan standar pengkodean dan format praktik terbaik dalam dokumen umum dan minta semua pengembang menyetujuinya.

Anda menyebut Git, yang hebat, karena didistribusikan. Dengan DVCS, sangat mudah untuk menegakkan praktik terbaik melalui alur kerja gatekeeper . Gatekeeper menolak proposal penggabungan (= menarik permintaan di Git) yang tidak sesuai dengan pedoman umum. Dan maksud saya tolak , dalam huruf tebal, jika pembuat kode yang melanggar tidak akan repot untuk mengikuti aturan dan terus mengulangi kesalahan yang sama.

Teknik ini bekerja dengan baik untuk saya. Coder ingin pekerjaan mereka digabung, jadi setelah beberapa kesalahan pada awalnya mereka mulai mengikuti aturan.

Sesuai memperbaiki basis kode yang ada ... Saya sarankan melakukan itu secara bertahap, mungkin modul demi modul, atau karena masuk akal untuk proyek Anda. Uji dengan cermat pada setiap langkah. Ini mungkin terdengar bodoh, tetapi kesalahan terjadi bahkan dengan perubahan sepele seperti hanya memformat, jadi bersiaplah untuk beberapa gundukan kecil di jalan.


1
Tunduk, karena penulisnya dengan jelas menyatakan ini dalam konteks proyek yang tidak dimulai dengan "... panduan gaya yang jelas, lengkap, dapat diverifikasi, dan diberlakukan mulai hari pertama". Dia tidak dapat mengobati masalah sebenarnya, karena itu sudah terjadi. Tapi saya setuju dengan Anda :)
Johntron

2
reject berarti akan ada pertarungan antara manusia dan robot. Pernah ke sana. Cepat atau lambat, robot akan membutuhkan potongan kode yang sangat rumit untuk diformat dengan cara yang tidak dapat dibaca. Contoh: string Java sebenarnya adalah pernyataan SQL, tetapi robot tidak tahu ini; spasi putih sebelum menutup parens dapat membawa informasi tentang struktur kode untuk manusia, tetapi tidak untuk robot; parameter fungsi terpecah di beberapa baris dengan cara yang paling tidak berarti ...
18446744073709551615

9

Jawaban untuk pertanyaan Anda yang sebenarnya adalah, "Anda tidak." Saya tahu tidak ada alat SCM saat ini yang dapat melacak perubahan dalam logika dari kode yang diformat dalam satu cara, melalui perubahan format utama, dan melalui perubahan lebih lanjut setelah kode diformat dengan cara baru. Dan, Anda tahu ini, kehilangan sejarah pada sepotong kode tidak baik.

Oleh karena itu, saya akan sedikit menentang kalimat pertama Anda. Kode format tidak peduli bahwa banyak. Cantik itu bagus, tapi bukan untuk apa kita di sini. Saya mengerti juga siapa pun yang dimasukkan ke kode varian K&R aneh neraka lama seseorang dengan indentasi dua-ruang menyebalkan (1), tapi ... memformat sebenarnya bukan halangan untuk memahami apa yang terjadi, kecuali itu sesuatu yang luar biasa patologi. Dan jika demikian, Anda tetap akan mengalami masalah dalam mengubah kode, dan tidak perlu repot-repot melakukannya.

Oleh karena itu, tidak layak untuk membuat perubahan pada kode yang telah ditetapkan dengan keras untuk memformat ulangnya. Mengubah nama variabel, memecah fungsi panjang, semua hal refactoring yang bagus yang mengubah konten, ya, tapi tidak HANYA memformat ulang.

1) - Saya pernah memiliki Windows Clipboard Viewer untuk sementara waktu. Semuanya adalah satu, 150k, modul C. Saya menemukan tempat di mana orang yang berbeda telah menggunakan, saya pikir, lima gaya penyangga yang berbeda dalam tiga puluh baris satu sama lain. Tapi itu bagian dari BEKERJA. Saya membawa sekitar cetakan dari potongan kode itu selama sepuluh tahun, tapi saya tidak menyodoknya karena sejarah itu penting, dan kode itu ada di setidaknya tiga pohon sumber (Windows 3.x, NT, masa depan 95) yang semuanya hidup di gedung yang berbeda.


Di masa lalu, menggunakan hg, saya telah menemukan bahwa menggabungkan-oleh-bagian adalah alat yang sangat berharga dalam mengatasi penggabungan faktor-faktor besar yang rumit . Biasanya yang akan saya lakukan adalah menggabungkan komit sebelum faktor ulang besar, lalu menggabungkan faktor ulang besar itu sendiri dan akhirnya menggabungkan komit sejak faktor ulang. Masing-masing tiga gabungan ini sendiri adalah jauh lebih mudah kemudian mencoba untuk menguraikan kekacauan bahwa hasil dari melakukan semua gabungan dalam satu pergi.
Mark Booth

Saya sangat setuju! Selain itu, saya telah melihat banyak pengembang berlebihan (termasuk versi saya yang lebih muda) tentang pemformatan ulang dan gaya kode, dan mereka akhirnya memperkenalkan cacat. Koma / titik koma yang hilang di sini, deklarasi variabel dipindahkan ke atas fungsi, untuk-loop diubah ke untuk masing-masing - mereka semua dapat memperkenalkan bug halus. Dibutuhkan sejumlah keterampilan menipu untuk melakukan perubahan ini dengan aman.
Johntron

4

Tetapi bagaimana Anda melacak perubahan kode di seluruh perubahan pemformatan utama?

Perubahan format adalah perubahan kode; perlakukan mereka seperti Anda akan mengubah kode Anda. Siapa pun yang telah mengerjakan proyek yang signifikan mungkin akan melihat bug dan masalah lain yang dibuat ketika seseorang memutuskan untuk "hanya" memformat ulang beberapa kode.

Tapi itu banyak pekerjaan, dan semua orang harus berhenti bekerja (atau bersiaplah untuk ibu dari semua penggabungan) saat sedang berlangsung.

Mengapa Anda harus memformat ulang semuanya pada saat yang bersamaan? Terutama jika pemformatan ulang tidak mengubah arti kode, Anda harus dapat memformat ulang file secara individual dan memeriksanya saat Anda melanjutkan. Lebih baik, mintalah semua orang di tim Anda untuk menyetujui gaya (jika tidak, tidak ada gunanya memformat ulang) dan minta mereka semua mengurus pemformatan ulang dalam pekerjaan mereka yang lain. Setelah beberapa saat, Anda akan membahas sebagian besar kode tanpa mengganggu sisa proyek.


1

Ada dua pendekatan yang saya lihat selama ini.

1. Memformat ulang kode pada commit-hook

Walaupun awalnya mengubah-ubah untuk mengubah kode setelah mereka mengirimkannya, jika prosedur pemformatan ulang Anda (misalnya astyle ) tidak merusak kode, maka ini merupakan operasi yang aman. Seiring waktu, seluruh tim akan menghargai bahwa semua kode pada akhirnya terlihat sama. Jelas, memiliki unit / tes otomatis yang komprehensif akan memastikan bahwa tidak ada yang rusak.

2. Pemformatan ulang satu kali untuk semua kode

Ini lebih berbahaya dalam pengalaman saya, dan membuat masalah pelacakan di big-bang sulit, tapi itu mungkin. Menjalankan semua tes setelah itu sangat penting. Untuk gaya pengkodean, sebagian besar perbedaan berkisar pada penggunaan spasi putih - indentasi atau baris baru. Alat penggabungan yang layak harus dapat dikatakan untuk mengabaikan semua perbedaan spasi putih, jadi ini akan membantu dengan penggabungan.


1
Bukankah opsi satu ketika dihidupkan riak di sebagian besar basis kode dengan cepat menghasilkan ledakan besar yang sama dari setiap perubahan file?
Masuk

@Sign: Persis maksud saya - Saat komit berubah, riwayat Anda bisa memburuk menjadi sesuatu yang hampir tidak berguna. Pemformatan yang tidak mengubah fungsi tidak boleh berupa komit, itu harus ditransplantasikan sepanjang sejarah kode.
l0b0

1
Jika dukungan IDE maka ada juga 3) memiliki autoformat IDE di save. Kemudian gunakan saja pengaturan yang sama di mana-mana - ini paling mudah jika Anda menggunakan default dengan IDE.

Saya telah melakukan kedua pendekatan ini. Pendekatan pertama sangat menonjol karena akan ada banyak perubahan setiap kali file baru dilakukan untuk pertama kalinya. Pendekatan kedua lebih baik untuk tim, seperti merobek bandaid dengan cepat.
Druska
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.