Kami sedang mengerjakan proyek, tetapi kami menggunakan kembali banyak kode di antara proyek dan memiliki banyak perpustakaan yang berisi kode umum kami. Saat kami mengimplementasikan proyek baru, kami menemukan lebih banyak cara untuk memfaktorkan kode umum dan memasukkannya ke perpustakaan. Perpustakaan bergantung satu sama lain, dan proyek tergantung pada perpustakaan. Setiap proyek, dan semua perpustakaan yang digunakan dalam proyek itu, perlu menggunakan versi yang sama dari semua perpustakaan yang mereka maksud. Jika kami merilis perangkat lunak, kami harus memperbaiki bug dan mungkin menambahkan fitur baru selama bertahun-tahun, terkadang selama beberapa dekade. Kami memiliki sekitar selusin perpustakaan, perubahan sering kali lebih dari dua, dan beberapa tim bekerja pada beberapa proyek secara paralel, membuat perubahan bersamaan untuk semua perpustakaan ini.
Kami baru saja beralih ke git dan mengatur repositori untuk setiap perpustakaan dan setiap proyek. Kami menggunakan simpanan sebagai repositori umum, melakukan hal-hal baru pada cabang fitur, lalu membuat permintaan tarik dan menggabungkannya hanya setelah ditinjau.
Banyak masalah yang harus kita tangani dalam proyek mengharuskan kita melakukan perubahan di beberapa perpustakaan dan kode spesifik proyek. Ini sering termasuk perubahan antarmuka perpustakaan, beberapa di antaranya tidak kompatibel. (Jika menurut Anda ini terdengar mencurigakan: Kami berinteraksi dengan perangkat keras, dan menyembunyikan perangkat keras tertentu di belakang antarmuka umum. Hampir setiap kali kami mengintegrasikan beberapa perangkat keras vendor lain, kami mengalami kasus-kasus yang tidak diantisipasi oleh antarmuka kami saat ini, sehingga harus disempurnakan.) Untuk misalnya, bayangkan sebuah proyek P1menggunakan perpustakaan L1, L2dan L3. L1juga menggunakan L2dan L3, dan L2menggunakan L3juga. Grafik ketergantungan terlihat seperti ini:
<-------L1<--+
P1 <----+ ^ |
<-+ | | |
| +--L2 |
| ^ |
| | |
+-----L3---+
Sekarang bayangkan sebuah fitur untuk proyek ini membutuhkan perubahan P1dan L3yang mengubah antarmuka L3. Sekarang tambahkan proyek P2dan P3ke dalam campuran, yang juga merujuk ke perpustakaan ini. Kami tidak mampu mengalihkan semuanya ke antarmuka baru, menjalankan semua tes, dan menggunakan perangkat lunak baru. Jadi apa alternatifnya?
- mengimplementasikan antarmuka baru di
L3 - buat permintaan tarik
L3dan tunggu ulasannya - gabungkan perubahan
- buat rilis baru
L3 - mulailah bekerja pada fitur
P1dengan membuatnya merujuk keL3rilis baru, kemudian mengimplementasikan fitur padaP1cabang fitur - buat permintaan tarik, periksa ini, dan bergabung
(Saya hanya memperhatikan bahwa saya lupa untuk beralih L1dan L2ke rilis baru. Dan saya bahkan tidak tahu di mana harus memasukkan ini, karena itu harus dilakukan bersamaan dengan P1...)
Ini adalah proses yang membosankan, rawan kesalahan, dan sangat panjang untuk mengimplementasikan fitur ini, perlu tinjauan independen (yang membuatnya jauh lebih sulit untuk ditinjau), tidak berskala sama sekali, dan cenderung membuat kami keluar dari bisnis karena kami terjebak dalam proses kami tidak pernah menyelesaikan apa pun.
Tetapi bagaimana kita menggunakan percabangan dan penandaan untuk menciptakan proses yang memungkinkan kita untuk mengimplementasikan fitur-fitur baru dalam proyek-proyek baru tanpa terlalu banyak overhead?