Bagaimana cara melakukan refactoring dalam proses?

23

Jadi, saya punya proyek besar ini, yang sedang dalam proses menjadi refactored oleh saya. Saya mengubah banyak hal, jadi tidak ada kesempatan untuk mendapatkannya dalam waktu dekat. Saya tinggal di cabang git khusus yang saya beri nama cleanup(yang akan digabungkan pada masterakhirnya, tentu saja).

Masalahnya adalah, saya / kami memiliki kebijakan untuk tidak pernah melakukan kode yang tidak dikompilasi (idealnya itu juga bisa berfungsi, tetapi harus dikompilasi dan dihubungkan, paling tidak). Jadi, sampai saya selesai dengan tugas besar ini, saya tidak dapat melakukan apa pun (untuk ditinjau atau untuk pembukuan).
Ini bukan cara saya suka bekerja (saya percaya kebanyakan orang berkomitmen setidaknya sekali sehari atau lebih).

Apa yang kamu pikirkan? Apakah ada solusi yang saya hadapi?
Bisakah nanti saya beri tahu git untuk menggabungkan komitmen atau sesuatu? Saya bisa hidup dengan komit yang tidak dikompilasi selama mereka tetap di cleanupcabang.

Edit

Untuk subjek mendorong / melakukan: Saya menyadari bahwa itu adalah perbedaan besar, tetapi nanti, akan ada revisi yang rusak, ketika saya menggabungkan barang-barang saya ke master. Jadi, jika Anda menelusuri sejarah (atau git bisect...) maka revisi "lokal" akan dapat diakses dunia. Jadi hanya melakukan secara lokal dan tidak mendorong bukanlah solusi terbaik, karena itu akan menyebabkan Anda kesulitan di kemudian hari (ketika subjek ditutup dan dilupakan untuk beberapa waktu).

Singkatnya: Komit lokal akan didorong pada akhirnya. Sejarah global seharusnya tidak menunjukkan komitmen yang tidak dikompilasi.

bitmask
sumber
1
Anda dapat mengumpulkan beberapa komit lokal dalam satu komit global.
@ Thorbjørn apakah itu rekomendasi Jim di bawah ini, atau mekanisme berbeda di dalam Git?
Brian
Saya percaya begitu - saya tidak dapat mengingat perintah yang tepat.
5
Anda tidak refactoring, Anda melakukan sesuatu yang lebih besar. Setelah setiap refactor pada basis kode, kode Anda harus mengkompilasi dan memiliki perilaku yang dapat diamati sama persis. Anda mungkin ingin mengubah judul pertanyaan Anda untuk mencerminkan hal itu, karena reaksi langsung saya adalah "Komit apa yang Anda punya kapan saja, semuanya harus bekerja".
David Thornley
1
@ bitmask Bagaimana kalau menulis ulang?
Dave Hillier

Jawaban:

21

The git merge --squashperintah memungkinkan Anda untuk membuat satu komit di atas cabang saat ini yang efeknya sama dengan penggabungan cabang lain. Perintah ini memperbarui pohon kerja dan tahapan perubahan dalam indeks, sehingga yang harus Anda lakukan selanjutnya adalah komit:

git checkout master
git merge --squash cleanup
git commit -m "Merge cleanup branch"

The git rebase -iperintah juga dapat labu komit tetapi membutuhkan lebih banyak pekerjaan.

Jim Huang
sumber
14

Menulis ulang bukanlah refactoring

Saya menyadari Anda tertarik pada cara menggunakan Git, tetapi saya berpendapat bahwa Anda harus mempertimbangkan untuk mengubah cara Anda melakukan refactoring lebih dari cara Anda menggunakan Git (walaupun saya pikir Git dapat membantu Anda).

Martin Fowler mendefinisikan refactoring sebagai :

suatu teknik disiplin untuk merestrukturisasi tubuh kode yang ada, mengubah struktur internalnya tanpa mengubah perilaku eksternalnya.

Jantungnya adalah serangkaian transformasi pelestarian perilaku kecil. Setiap transformasi (disebut "refactoring") tidak banyak berpengaruh, tetapi serangkaian transformasi dapat menghasilkan restrukturisasi yang signifikan. Karena setiap refactoring kecil, itu cenderung salah. Sistem ini tetap berfungsi penuh setelah setiap refactoring kecil, mengurangi kemungkinan bahwa suatu sistem dapat rusak parah selama restrukturisasi.

Jika Anda menerapkan metode ini, Anda dapat melakukan (dan mendorong) secara teratur.

Anda mungkin berpendapat bahwa ini tidak praktis, dan itu tidak berhasil untuk skala besar. Di sinilah metode Mikado dapat membantu. Anda menguraikan refactoring besar menjadi serangkaian refactoring kecil dengan membuat grafik dependensi. Metode ini bersifat rekursif, mencoba membuat perubahan, tidak merusak apa pun memeriksanya, jika tidak, kembalikan perubahan Anda dan buat catatan tentang prasyarat. Satu per satu, Anda memperbaiki refactor yang diperlukan sebelum Anda mencapai tujuan refactoring utama Anda.

Git benar-benar dapat membantu metode ini. Anda dapat menyimpan cabang lokal Anda (rusak). Saat Anda melakukan (dan menekan) sub-sasaran, Anda dapat rebasemembuat cabang sasaran utama Anda di atas semua komitmen yang baru saja Anda buat, sampai tidak lagi rusak.

Dave Hillier
sumber
5

Lihat halaman manual untuk git rebase, khususnya git rebase -ivarian. Ini memungkinkan Anda untuk memesan ulang, menghapus, atau menghancurkan sejumlah komit dalam riwayat Anda, yang kedengarannya seperti apa yang Anda cari. Saya menggunakannya sepanjang waktu dalam situasi yang Anda jelaskan: membuat banyak komitmen kecil yang tidak sesuai untuk konsumsi publik, lalu menyatukannya menjadi satu komitmen "refactoring" sebelum mendorong ke repositori bersama.


sumber
3

Anda menggunakan Git, jadi komit tidak selalu berarti mendorong perubahan Anda ....

IMHO, dan bekerja dengan Git, sangat baik untuk mengkomit pekerjaan Anda, bahkan jika itu tidak dikompilasi ... karena, setelah semua, setelah Anda mengkomit perubahan Anda, tidak ada yang akan memiliki kode yang tersedia (sampai Anda mendorongnya). Tentu saja, sebelum mendorongnya, Anda harus memastikan itu berfungsi dengan baik dan kompilasi, sehingga orang lain dapat mengambil dan menggabungkan perubahan Anda tanpa masalah.

Selain itu, Anda bekerja pada cabang yang berbeda dari cabang utama. Jadi, jika Anda mau (dan saya merekomendasikan ini), Anda tidak akan pernah mendorong cabang Anda. Setelah Anda menyelesaikan refactoring, cukup checkout cabang master, gabungkan perubahan Anda dan tekan cabang master.

Edit

Dalam hal ini Anda dapat menggunakan git cherry-pickatau bermain-main dengangit rebase

Cristian
sumber
Catatan penting, tetapi saya mempertimbangkan ini. Silakan lihat edit saya. Terima kasih.
bitmask
Lihat hasil edit saya di atas.
Cristian
Saya akan -1 jika saya bisa; komit akan tersedia! Komitmen pekerjaan dalam proses lokal bagus, tetapi tidak pernah mendorongnya; itu membuat kode lebih sulit untuk dipahami, memotong git dua bagian, dan memperumit sejarah. Rebase atau squash saja.
RJFalconer