Strategi untuk menggabungkan 1 tahun pengembangan di Visual Studio

32

Saya punya klien yang bersikeras agar kami memisahkan pengembangan baru dari cabang utama sepanjang 2016. Mereka memiliki 3-4 tim lain yang mengerjakan aplikasi dalam berbagai kapasitas. Banyak perubahan besar telah dibuat (mengubah cara injeksi ketergantungan dilakukan, membersihkan kode dengan ReSharper, dll). Sekarang telah jatuh pada saya untuk menggabungkan utama ke cabang dev baru kami untuk bersiap mendorong perubahan kami ke atas rantai.

Pada penggabungan awal saya, TFS melaporkan ~ 6500 file dengan resolusi konflik. Beberapa di antaranya akan mudah, tetapi beberapa di antaranya akan jauh lebih sulit (khususnya beberapa javascript, pengontrol api, dan layanan yang mendukung pengontrol ini).

Apakah ada pendekatan yang bisa saya ambil yang akan membuat ini lebih mudah bagi saya?

Untuk memperjelas, saya menyatakan banyak keprihatinan dengan pendekatan ini beberapa kali di sepanjang jalan. Klien sudah dan menyadari kesulitan dengan ini. Karena mereka memilih untuk kekurangan staf QA (1 tester untuk 4 devs, tidak ada pengujian otomatis, pengujian regresi kecil), mereka bersikeras bahwa kami menjaga cabang kami diisolasi dari perubahan di cabang utama dengan alasan bahwa ini akan mengurangi kebutuhan untuk kami tester untuk mengetahui tentang perubahan yang dilakukan di tempat lain.

Salah satu masalah yang lebih besar di sini adalah peningkatan ke versi sudut dan beberapa perangkat lunak pihak ketiga lainnya - sayangnya kita belum menemukan cara yang baik untuk membangun solusi ini sampai semua bagian dimasukkan kembali ke tempatnya.

pengguna258451
sumber
63
Nggak. Anda memiliki dua cabang terpisah yang aktif dikembangkan selama satu tahun. Penggabungan akan menyedot.
17 dari 26
2
Berapa luas perubahan yang dilakukan tim Anda? Mungkin lebih efisien untuk mengidentifikasi perubahan itu dan kemudian secara manual menerapkannya kembali ke basis kode master saat ini.
kdgregory
2
Apakah keseluruhan 2015 atau 2016? Jika 2015 nya 2 tahun, yang berarti akan dua kali lipat.
David berkata Reinstate Monica
1
Mengapa klien peduli jika pekerjaan yang Anda lakukan untuk mereka ada di cabang terpisah di sistem kontrol versi Anda?
Ixrec
17
Apa pun yang Anda lakukan, pastikan Anda menagih setiap jam.
Sean McSomething

Jawaban:

37

Akan ada cara sederhana yang telah membuat pengembangan baru Anda terpisah dari cabang utama tanpa membawa Anda ke dalam situasi yang tidak menguntungkan ini: setiap perubahan dari bagasi harus digabung ke cabang dev Anda setiap hari . (Apakah klien Anda benar-benar picik sehingga ia tidak bisa mengantisipasi bahwa kantor cabang Anda perlu dipasang kembali ke jalur utama suatu hari nanti?)

Bagaimanapun, pendekatan terbaik adalah IMHO yang mencoba mengulang apa yang seharusnya terjadi di tangan pertama:

  • mengidentifikasi semantik dari perubahan pada jalur utama untuk hari 1 setelah cabang dibuat. Menerapkannya ke basis kode Anda saat ini sebaik mungkin. Jika itu adalah "perubahan lokal", itu harus sederhana, jika itu adalah "cross cutting refactoring" seperti mengubah nama kelas yang banyak digunakan, menerapkannya secara semantik setara dengan basis kode Anda saat ini. Mudah-mudahan selama tahun itu tidak ada perubahan lintas-basis yang kontradiktif dalam basis kode yang dibuat pada cabang "Anda", jika tidak, ini bisa menjadi penggila otak yang nyata
  • uji hasilnya (apakah saya menyebutkan Anda membutuhkan test suite yang baik untuk tugas ini)? Perbaiki semua bug yang diungkapkan oleh tes
  • sekarang ulangi proses ini untuk perubahan pada jalur utama untuk hari 2, lalu hari 3, dan seterusnya.

Ini mungkin bekerja ketika tim secara ketat mematuhi aturan klasik kontrol versi ("hanya melakukan kondisi yang dapat dikompilasi, diuji" dan "check in lebih awal dan sering").

Setelah 365 pengulangan (atau 250, jika Anda beruntung dan Anda dapat menggabungkan pekerjaan untuk perubahan akhir pekan), Anda akan hampir selesai (hampir, karena Anda perlu menambahkan jumlah perubahan yang akan terjadi pada jalur utama selama periode integrasi ). Langkah terakhir adalah menggabungkan cabang dev yang diperbarui ke dalam trunk lagi (jadi Anda tidak kehilangan sejarah trunk). Ini harus mudah, karena secara teknis itu hanya penggantian file yang terpengaruh.

Dan ya, saya serius, mungkin tidak ada jalan pintas untuk ini. Mungkin ternyata "porsi harian" mungkin kadang-kadang terlalu kecil, tapi saya tidak berharap ini, saya kira itu kemungkinan porsi harian bisa berubah menjadi terlalu besar. Saya harap klien Anda membayar Anda dengan sangat baik untuk ini, dan bahwa ini sangat mahal baginya sehingga ia akan belajar dari kegagalannya.

Saya harus menambahkan bahwa Anda dapat mencoba ini juga dengan sisi yang diaktifkan - mengintegrasikan kembali perubahan dari cabang Anda dalam porsi kecil ke jalur utama. Ini mungkin lebih sederhana ketika di cabang dev Anda ada perubahan jauh lebih sedikit daripada di bagasi, atau sebagian besar perubahan terjadi pada file sumber baru yang saat ini bukan bagian dari bagasi. Orang dapat melihat ini sebagai "porting" suatu fitur dari produk A (cabang dev) ke produk B yang agak berbeda (kondisi batang saat ini). Tetapi jika sebagian besar refactor lintas sektoral dilakukan pada jalur utama, dan itu mempengaruhi kode baru Anda (6500 gabungan tabrakan tampaknya menjadi beberapa bukti untuk ini), mungkin lebih mudah dengan cara saya menggambarkannya terlebih dahulu.

Doc Brown
sumber
9
Jika Anda melanjutkan pengembangan pada trunk saat re-integrasi, saya sarankan Anda menaburkan ujung trunk terlebih dahulu dan mengembangkannya. Kalau tidak, Anda secara efektif menggabungkan masa lalu dan masa depan secara bersamaan. Tapi saya tunduk pada Doc Brown tentang diskontinuitas ruang-waktu, secara alami.
radarbob
1
@radarbob: apa yang Anda sarankan hanya masuk akal jika OP berintegrasi dari dev ke trunk, tetapi tidak ketika ia memutuskan untuk menggabungkan dari trunk ke dev, seperti yang saya jelaskan pertama kali. Jika OP mentransfer perubahan dari trunk ke cabang dev-nya setiap hari (dimulai dengan perubahan 365 hari di masa lalu), tidak masalah jika pengembangan pada trunk berlangsung. Dia hanya perlu melanjutkan taktik ini sampai dia mencapai saat ini (dengan asumsi dia dapat mengintegrasikan & menguji perubahan 3-4 tim pada satu hari dalam waktu kurang dari satu hari).
Doc Brown
Kutipan: "Saya harus menambahkan bahwa Anda dapat mencoba ini juga dengan sisi-sisi yang beralih - mengintegrasikan kembali perubahan dari cabang Anda dalam bundel harian ke jalur utama. " Perasaan spidey saya sedang meniup sekring. Saya merasakan kaskade potensial "distorsi resonansi harmonik" dengan integrasi perubahan yang saling bertentangan.
radarbob
Ini saran yang bagus. Lihat edit untuk membahas beberapa hal di sini.
user258451
1
@ user258451: jadi Anda punya tim QA berbeda untuk bagasi dan cabang dev baru di tempat yang tidak ingin berbicara satu sama lain? Great Scott: - ((
Doc Brown
14

Pada tahap penggabungan, saya akan mengatakan bahwa penggabungan otomatis hanya dapat memperumit proses. Saya memiliki masalah serupa dengan cabang yang telah menyimpang selama lebih dari setahun dan metode paling efektif yang saya miliki adalah dengan melakukan hal berikut:

  • Ambil satu salinan dari kondisi tanpa pencemaran asli
  • Perbedaan antara yang tidak digarap dan yang terbaru
  • Hancurkan setiap elemen umum
    • Misalnya, lakukan semua perubahan nama fungsi, lalu perubahan parameter, dll.
    • Abaikan ruang putih pada diff jika standar telah berubah, jika tidak, Anda akan membuang banyak waktu untuk menghitung ruang
  • Fokus pada fungsionalitas inti terlebih dahulu

Akhirnya kompiler peringatan dan diff akan menjadi teman terbaik Anda, tetap menggunakan diff unmerged untuk melihat apa yang berbeda dan terus berjalan. Mungkin ada berbagai alat yang dapat Anda gunakan untuk membantu, tetapi terserah Anda untuk menemukan mana yang terbaik.

Kuncinya adalah terus berjalan.

Edit:

Sebagai peringatan, pendekatan ini akan berarti bahwa sejarah kontrol versi akan menjadi 'rusak', karena Anda akan kehilangan bukti penggabungan cabang-ke-cabang, serta sejarah cabang yang tidak digeser.

Terima kasih atas komentar dari 'Jack Aidley' dan '17 of 26 '

Erdrik Ironrose
sumber
1
Masalah utama dengan pendekatan ini adalah bahwa hal itu akan menghancurkan catatan perubahan yang tersisa di sistem kontrol versi.
Jack Aidley
Pada dasarnya dengan membuat semua perubahan yang sama untuk kedua kalinya selama penggabungan, Anda masih memiliki log perubahan, itu hanya akan berada dalam urutan yang dilakukan dalam penggabungan bukan urutan yang mereka lakukan selama pengembangan. Tidak ideal, tetapi lebih baik daripada tidak sama sekali. Ditambah lagi, Anda masih memiliki kondisi tidak terputus yang asli, jika itu tetap di kontrol versi.
Erdrik Ironrose
Anda akan memiliki log perubahan, tetapi Anda tidak akan memiliki bukti historis bahwa perubahan digabung dari cabang ke cabang. Ini akan menjadi masalah besar di TFS, yang menawarkan Anda hanya perubahan yang tidak dihapus untuk dipilih saat menggabungkan dari cabang ke cabang.
17 dari 26
@ 17of26 Meskipun saya setuju bahwa Anda dapat mengembalikan beberapa catatan perubahan, 17 dari 26 benar bahwa catatan ini tidak akan lengkap atau akurat. Mungkin saja pendekatan ini cukup mudah untuk menjadikan hilangnya catatan ini kompromi yang dapat diterima mengingat situasi buruk yang mereka hadapi sekarang. Namun, saya pikir ini adalah kelemahan penting untuk dikenali terlepas dari apa yang mereka putuskan.
Jack Aidley
1
@ Jack Aidley Saya sangat setuju itu cukup masalah, jadi saya telah menambahkan sedikit jawaban saya untuk mencerminkan. Saya harap tidak apa-apa?
Erdrik Ironrose
8

Beberapa tahun yang lalu kami memiliki klien dengan persyaratan yang sama untuk memisahkan cabang. Jadi kami melakukannya.

Kami tidak pernah menggabungkan cabang mereka kembali. Mereka punya versi unik di sana. Kami menagih mereka ekstra untuk perubahan karena pada dasarnya kami memiliki dua batang utama bukan 1 batang utama dan cabang.

Kami berusaha untuk bergabung kembali ke bagasi, tetapi setelah 2 minggu kami memutuskan untuk meninggalkan upaya itu karena itu menghabiskan waktu berjam-jam tanpa manfaat nyata.

Jadi, jangan gabungkan kembali. Ke depannya, gabungkan perbaikan-perbaikan penting ke cabang klien sebagaimana diperlukan dan peningkatan apa pun akan menjadi salah satu diskon yang secara khusus dibebankan kepada klien itu.

Jon Raynor
sumber
Strategi ini hanya layak jika jalur pengembangan yang berbeda menargetkan klien yang berbeda. Atau, jika kasus penggunaan di mana produk terlibat memungkinkan untuk menggunakan dua lini produk yang berbeda secara paralel, dengan cara yang tidak terintegrasi. Menurut pemahaman saya, OP menggambarkan situasi di mana jalur pengembangan baru menargetkan klien yang sama dengan orang yang menggunakan bagasi, dan tidak jelas apakah penggunaan paralel dua lini produk bisa masuk akal untuk kasusnya.
Doc Brown
1

Ini tidak akan menyenangkan, tetapi seberapa menyakitkan itu akan tergantung pada sifat perubahan, dan seberapa terisolasi mereka.

Saya sarankan Anda mencoba untuk menyatukan cabang-cabang melalui refactoring sebanyak mungkin sebelum Anda melakukan penggabungan yang sebenarnya.

Alat penggabungan agak bodoh karena hanya melihat perbedaan tekstual dan tidak mengerti kode dengan cara apa pun. Jika cabang utama telah mengubah nama kelas yang digunakan di seluruh aplikasi, dan cabang fitur menggunakan nama lama dalam beberapa kode baru, maka alat gabungan tidak akan mengerti bahwa nama kelas juga harus diubah dalam kode baru. Tetapi jika Anda melakukan refactoring di cabang B untuk mengubah nama kelas seperti di cabang A itu akan bekerja di kedua kode lama dan baru dan penggabungan akan berjalan dengan lancar.

Kedua, Anda harus memeriksa seberapa lokal perubahan di cabang pengembangan. Jika perubahan dalam cabang fitur dilokalkan ke beberapa area, Anda tidak harus menyatukan kode yang tidak terpengaruh, Anda bisa menyalin dan menimpa dari cabang utama.

Di area kode di mana ada perubahan non-sepele pada kedua cabang, Anda harus hati-hati memeriksa kode dan memutuskan bagaimana menulis ulang.

JacquesB
sumber