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 P1
menggunakan perpustakaan L1
, L2
dan L3
. L1
juga menggunakan L2
dan L3
, dan L2
menggunakan L3
juga. Grafik ketergantungan terlihat seperti ini:
<-------L1<--+
P1 <----+ ^ |
<-+ | | |
| +--L2 |
| ^ |
| | |
+-----L3---+
Sekarang bayangkan sebuah fitur untuk proyek ini membutuhkan perubahan P1
dan L3
yang mengubah antarmuka L3
. Sekarang tambahkan proyek P2
dan P3
ke 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
L3
dan tunggu ulasannya - gabungkan perubahan
- buat rilis baru
L3
- mulailah bekerja pada fitur
P1
dengan membuatnya merujuk keL3
rilis baru, kemudian mengimplementasikan fitur padaP1
cabang fitur - buat permintaan tarik, periksa ini, dan bergabung
(Saya hanya memperhatikan bahwa saya lupa untuk beralih L1
dan L2
ke 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?