Penjelasan Aliran Git yang Ditingkatkan

Diterbitkan: 2022-03-11

Secara tidak sengaja menyebabkan kerusakan dengan Git bisa sangat mudah. Namun, cara terbaik untuk menggunakan Git akan selalu kontroversial.

Itu karena Git sendiri hanya merinci operasi percabangan dasar, yang membiarkan pola penggunaannya—yaitu, model percabangan—masalah pendapat pengguna. Model percabangan Git berjanji untuk meringankan rasa sakit dengan mengatur kekacauan yang pasti muncul saat pengembang perangkat lunak membuat perubahan pada basis kode mereka.

Seperti banyak pengembang, Anda menginginkan sesuatu yang "berfungsi" sehingga Anda dapat melanjutkan pengembangan perangkat lunak yang sebenarnya. Jadi, Anda mengambil Git flow , model percabangan yang sering direkomendasikan kepada pengguna Git. Mungkin Anda sudah terbiasa dengan logika aliran Git pada awalnya, sampai Anda menemukan beberapa hambatan dalam praktiknya. Atau mungkin aliran Git sepertinya tidak cukup cocok untuk Anda adopsi. Lagi pula, ada banyak variabel yang berperan, dan tidak ada model percabangan tunggal yang akan bekerja dengan baik di setiap situasi.

Kabar baik! Variasi dari model aliran Git klasik, aliran Git yang disempurnakan menyederhanakan manuver yang lebih umum dari alur kerja aliran Git sambil tetap mempertahankan keunggulan utama.

Kemegahan dan Kesengsaraan Model Aliran Git Klasik

Saya telah menjadi pendukung kuat aliran Git sejak saya menemukan keunggulannya saat mengembangkan produk yang berkembang dalam peningkatan nilai yang signifikan (dengan kata lain, releases ).

Peningkatan nilai yang signifikan membutuhkan banyak waktu untuk diselesaikan, seperti sprint dua minggu lebih yang biasanya digunakan dalam pengembangan berbasis Scrum. Jika tim pengembangan telah dikerahkan ke produksi, mungkin ada masalah jika cakupan rilis berikutnya terakumulasi di tempat yang sama di mana kode produksi berada—misalnya, di cabang utama repo Git yang mereka gunakan.

Sementara produk masih dalam tahap pengembangan awal—yaitu, tidak ada produksi dan tidak ada pengguna produk yang sebenarnya—tidak apa-apa bagi tim untuk menyimpan semuanya di dalam cabang utama. Faktanya, ini lebih dari cukup: Strategi ini memungkinkan laju perkembangan tercepat tanpa banyak upacara. Tetapi banyak hal berubah dalam lingkungan produksi; kemudian, orang-orang nyata mulai mengandalkan produk untuk menjadi stabil.

Misalnya, jika ada bug kritis dalam produksi yang perlu segera diperbaiki, akan menjadi bencana besar bagi tim pengembangan jika harus memutar kembali semua pekerjaan yang diperoleh di cabang utama sejauh ini hanya untuk menerapkan perbaikan. Dan menerapkan kode tanpa pengujian yang tepat—apakah kode tersebut dianggap setengah matang atau dikembangkan dengan baik—jelas bukan pilihan.

Di situlah model percabangan bersinar, termasuk aliran Git. Setiap model percabangan yang canggih harus menjawab pertanyaan tentang cara mengisolasi rilis berikutnya dari versi sistem yang saat ini digunakan oleh orang-orang, cara memperbarui versi itu dengan rilis berikutnya, dan cara memperkenalkan perbaikan terbaru dari setiap bug kritis ke versi saat ini.

Proses aliran Git membahas skenario mendasar ini dengan memisahkan "main" (cabang produksi atau "versi saat ini") dan "develop" (cabang pengembangan atau "rilis berikutnya") dan menyediakan semua aturan tentang penggunaan cabang fitur/rilis/perbaikan terbaru . Ini secara efektif memecahkan banyak sakit kepala dari alur kerja pengembangan produk berbasis rilis.

Tetapi bahkan dengan proyek yang sangat cocok dengan model aliran Git klasik, saya telah mengalami masalah khas yang dapat ditimbulkannya:

  • Aliran Git rumit, dengan dua cabang berumur panjang, tiga jenis cabang sementara, dan aturan ketat tentang bagaimana cabang berhubungan satu sama lain. Kompleksitas seperti itu membuat kesalahan lebih mungkin terjadi dan meningkatkan upaya yang diperlukan untuk memperbaikinya.
  • Cabang rilis dan perbaikan terbaru memerlukan "penggabungan ganda"—sekali menjadi utama, lalu menjadi berkembang. Terkadang Anda bisa lupa melakukan keduanya. Anda dapat membuat percabangan aliran Git lebih mudah dengan skrip atau plugin klien GUI VCS, tetapi Anda harus mengaturnya terlebih dahulu untuk setiap mesin dari setiap pengembang yang terlibat dalam proyek tertentu.
  • Dalam alur kerja CI/CD, Anda biasanya berakhir dengan dua build final untuk rilis—satu dari komit terbaru dari cabang rilis itu sendiri dan satu lagi dari komit gabungan ke main. Sebenarnya, Anda harus menggunakan yang utama, tetapi keduanya biasanya identik, menciptakan potensi kebingungan.

Masukkan "Aliran Git yang Ditingkatkan"

Pertama kali saya menggunakan aliran Git yang ditingkatkan adalah pada proyek sumber tertutup yang ramah lingkungan. Saya bekerja dengan satu pengembang lain, dan kami telah mengerjakan proyek dengan berkomitmen langsung ke cabang utama.

Catatan: Hingga rilis publik pertama suatu produk, sangat masuk akal untuk melakukan semua perubahan secara langsung ke cabang utama—bahkan jika Anda adalah pendukung aliran Git—demi kecepatan dan kesederhanaan alur kerja pengembangan. Karena belum ada produksi, tidak ada kemungkinan bug produksi yang perlu diperbaiki tim secepatnya. Oleh karena itu, melakukan semua keajaiban percabangan yang disiratkan oleh aliran Git klasik terlalu berlebihan pada tahap ini.

Kemudian kami mendekati rilis awal dan kami sepakat bahwa, di luar titik itu, kami tidak akan merasa nyaman lagi dengan melakukan langsung ke cabang utama. Kami telah bergerak cukup cepat, dan prioritas bisnis tidak meninggalkan banyak ruang untuk membangun proses pengembangan yang kokoh—yakni, proses dengan pengujian otomatis yang cukup untuk memberi kami keyakinan bahwa cabang utama kami tetap dalam keadaan siap rilis.

Tampaknya menjadi kasus yang valid untuk model aliran Git klasik. Dengan cabang utama dan pengembangan yang terpisah dan waktu yang cukup antara peningkatan nilai yang signifikan, ada keyakinan bahwa sebagian besar QA manual akan memberikan hasil yang cukup baik. Ketika saya menganjurkan aliran Git, rekan saya menyarankan sesuatu yang serupa, tetapi dengan beberapa perbedaan utama.

Pada awalnya, saya mendorong kembali. Bagi saya, beberapa "tambalan" yang diusulkan untuk aliran Git klasik agak terlalu revolusioner. Saya pikir mereka mungkin melanggar ide utama, dan seluruh pendekatan akan gagal. Tetapi dengan pemikiran lebih lanjut, saya menyadari bahwa tweak ini tidak benar-benar merusak aliran Git. Sementara itu, mereka menjadikannya model percabangan Git yang lebih baik dengan menyelesaikan semua poin masalah yang disebutkan di atas.

Setelah sukses dengan pendekatan yang dimodifikasi dalam proyek itu, saya telah menggunakannya dalam proyek sumber tertutup lain dengan tim kecil di belakangnya, di mana saya adalah pemilik basis kode permanen dan satu atau dua pengembang outsourcing dari waktu ke waktu. Pada proyek ini, kami memasuki produksi enam bulan, dan sejak itu, kami telah menggunakan pengujian CI dan E2E selama lebih dari setahun, dengan rilis setiap bulan atau lebih.

Grafik komit Git tipikal saat menggunakan aliran Git yang ditingkatkan. Grafik menunjukkan beberapa komit pada pengembangan dan utama, dan sebelum komit umum mereka, beberapa tag berbasis tanggal.

Pengalaman saya secara keseluruhan dengan pendekatan percabangan baru ini sangat positif sehingga saya ingin membaginya dengan sesama pengembang untuk membantu mereka mengatasi kekurangan aliran Git klasik.

Persamaan dengan Aliran Git Klasik: Isolasi Pengembangan

Untuk isolasi kerja dalam aliran Git yang ditingkatkan, masih ada dua cabang berumur panjang, utama dan berkembang. (Pengguna masih memiliki perbaikan terbaru dan kemampuan rilis—dengan penekanan pada "kemampuan", karena ini bukan cabang lagi. Kami akan membahas detailnya di bagian perbedaan.)

Tidak ada skema penamaan resmi untuk cabang fitur aliran Git klasik. Anda baru saja keluar dari pengembangan dan bergabung kembali untuk mengembangkan saat fitur sudah siap. Tim dapat menggunakan konvensi penamaan apa pun yang mereka inginkan atau hanya berharap pengembang akan menggunakan nama yang lebih deskriptif daripada "cabang saya". Hal yang sama berlaku untuk aliran Git yang ditingkatkan.

Semua fitur yang terakumulasi di cabang pengembangan hingga beberapa titik batas akan membentuk rilis baru.

Gabungan Labu

Saya sangat menyarankan menggunakan squash merge untuk cabang fitur untuk menjaga sejarah tetap bagus dan linier sebagian besar waktu. Tanpa itu, grafik komit (dari alat GUI atau git log --graph ) mulai terlihat ceroboh ketika sebuah tim menyulap beberapa cabang fitur:

Membandingkan grafik komit yang dihasilkan dari strategi gabungan squash dengan yang dihasilkan dari strategi komit gabungan. Grafik komit Git awal memiliki cabang utamanya berlabel "develop," dengan komit sebelumnya memiliki "fitur-D" dan "fitur-C" bercabang darinya, dan komit yang lebih awal memiliki "fitur-B" dan "fitur-A " bercabang dari itu. Hasil komit gabungan terlihat serupa, tetapi dengan setiap cabang fitur menyebabkan komit baru pada pengembangan pada titik di mana ia mengikatnya kembali. Hasil penggabungan squash telah berkembang hanya sebagai garis lurus komit, tanpa cabang lain.

Tetapi bahkan jika Anda setuju dengan visual dalam skenario ini, ada alasan lain untuk berhenti. Tanpa meremas, komit tampilan riwayat—di antaranya git log biasa (tanpa --graph ) dan juga GitHub—ceritakan kisah yang agak tidak koheren bahkan dengan skenario penggabungan yang paling sederhana:

Membandingkan tampilan riwayat komit yang dihasilkan dari taktik gabungan squash dengan yang dihasilkan dari taktik komit gabungan. Status repo asli diberikan dalam bentuk garis waktu, menunjukkan kronologi komitmen ke dua cabang fitur yang berasal dari komit umum "x" pada pengembangan, komitmen bergantian antara cabang, yaitu dalam urutan 1a, 2a, 1b, dan 2b. Gabungkan hasil komit ditampilkan dalam dua variasi. Dalam riwayat komit yang dihasilkan dari menggabungkan cabang kedua, menggabungkan cabang pertama, lalu menghapus kedua cabang, ceritanya kronologis, tetapi tidak kohesif, dan termasuk komit gabungan tambahan untuk cabang pertama. Dalam riwayat yang dihasilkan dari penggabungan cabang-cabang secara berurutan sebelum menghapusnya, komit diurutkan, "x, 2a, 1a, 2b, 1b," diikuti oleh komit gabungan untuk cabang kedua, yang bahkan tidak kronologis. Riwayat komit dari penggabungan squash hanya memiliki satu komit untuk setiap cabang fitur, dengan kisah setiap cabang diceritakan oleh pembuatnya.

Peringatan untuk menggunakan penggabungan squash adalah bahwa riwayat cabang fitur asli hilang. Tetapi peringatan ini bahkan tidak berlaku jika Anda menggunakan GitHub, misalnya, yang memperlihatkan riwayat asli lengkap dari cabang fitur melalui permintaan tarik yang digabungkan dengan squash, bahkan setelah cabang fitur itu sendiri dihapus.

Perbedaan dari Aliran Git Klasik: Rilis dan Perbaikan Terbaru

Mari kita melalui siklus rilis karena (semoga) ini adalah hal utama yang akan Anda lakukan. Ketika kami sampai pada titik di mana kami ingin merilis apa yang terakumulasi dalam pengembangan, itu benar-benar superset dari main. Setelah itu, perbedaan terbesar antara aliran Git klasik dan yang disempurnakan dimulai.

Git melakukan grafik saat berubah saat melakukan rilis normal di bawah aliran Git yang ditingkatkan. Grafik awal memiliki penyimpangan utama dari mengembangkan beberapa komit di belakang tip dan oleh satu komit. Setelah penandaan, main dan vYYYY-MM-DD genap satu sama lain. Setelah menghapus main lokal, membuatnya di ujung pengembangan, dorongan paksa, penggelaran, pengujian, dll., main ditampilkan bahkan dengan pengembangan, meninggalkan vYYYY-MM-DD di mana main awalnya berada. Setelah siklus penyebaran/pengujian, pementasan perbaikan pada main (akhirnya squash bergabung menjadi pengembangan), dan sementara itu, perubahan yang tidak terkait pada pengembangan, grafik terakhir telah berkembang dan divergen utama, masing-masing dengan beberapa komit, dari mana mereka bahkan satu sama lain dalam grafik sebelumnya.

Rilis dalam Aliran Git yang Ditingkatkan

Setiap langkah membuat rilis dengan aliran Git yang ditingkatkan berbeda dari proses aliran Git klasik:

  1. Rilis didasarkan pada utama, bukan berkembang. Tandai ujung cabang utama saat ini dengan sesuatu yang berarti. Saya mengadopsi tag berdasarkan tanggal saat ini dalam format ISO 8601 yang diawali dengan "v"—misalnya, v2020-09-09 .
    • Jika ada beberapa rilis dalam satu hari—misalnya, hotfix—formatnya dapat memiliki nomor urut atau huruf yang ditempelkan sesuai kebutuhan.
    • Ketahuilah bahwa tag secara umum tidak sesuai dengan tanggal rilis. Mereka hanya memaksa Git untuk tetap mengacu pada bagaimana cabang utama terlihat saat proses rilis berikutnya dimulai.
  2. Dorong tag menggunakan git push origin <the new tag name> .
  3. Setelah itu, sedikit kejutan: hapus cabang utama lokal Anda . Jangan khawatir, karena kami akan segera memulihkannya.
    • Semua commit ke main masih aman—kami melindunginya dari pengumpulan sampah dengan menandai main pada langkah sebelumnya. Setiap komit ini—bahkan hotfix, seperti yang akan segera kita bahas—juga merupakan bagian dari pengembangan.
    • Pastikan hanya satu orang dalam tim yang melakukan ini untuk rilis tertentu; itulah yang disebut peran "manajer rilis". Manajer rilis biasanya adalah anggota tim yang paling berpengalaman dan/atau paling senior, tetapi sebuah tim akan bijaksana untuk menghindari anggota tim tertentu mengambil peran ini secara permanen. Lebih masuk akal untuk menyebarkan pengetahuan di antara tim untuk meningkatkan faktor bus yang terkenal.
  4. Buat cabang utama lokal baru di ujung komit cabang pengembangan Anda .
  5. Dorong struktur baru ini menggunakan git push --force , karena repo jarak jauh tidak akan menerima "perubahan drastis" seperti itu dengan mudah. Sekali lagi, ini tidak seaman kelihatannya dalam konteks ini karena:
    • Kami hanya memindahkan penunjuk cabang utama dari satu komit ke komit lainnya.
    • Hanya satu anggota tim tertentu yang melakukan perubahan ini pada satu waktu.
    • Pekerjaan pengembangan sehari-hari terjadi di cabang pengembangan, jadi Anda tidak akan mengganggu pekerjaan siapa pun dengan memindahkan main dengan cara ini.
  6. Anda memiliki rilis baru Anda! Menyebarkannya ke lingkungan pementasan dan mengujinya. (Kita akan membahas pola CI/CD yang nyaman di bawah ini.) Setiap perbaikan langsung ke cabang utama, dan itu akan mulai menyimpang dari cabang pengembangan karena itu.
    • Pada saat yang sama, Anda dapat mulai mengerjakan rilis baru di cabang pengembangan, keuntungan yang sama terlihat pada aliran Git klasik.
    • Dalam kejadian yang tidak menguntungkan bahwa perbaikan terbaru diperlukan untuk apa yang saat ini dalam produksi (bukan rilis yang akan datang dalam tahap) pada saat ini, ada detail lebih lanjut tentang skenario ini di "Berurusan dengan perbaikan terbaru selama rilis aktif ..." di bawah ini.
  7. Ketika rilis baru Anda dianggap cukup stabil, terapkan versi final ke lingkungan produksi dan lakukan satu squash merge dari main untuk mengembangkan untuk mengambil semua perbaikan.

Perbaikan terbaru dalam Aliran Git yang Ditingkatkan

Kasus hotfix ada dua. Jika Anda melakukan perbaikan terbaru saat tidak ada rilis aktif —yaitu, tim sedang mempersiapkan rilis baru di cabang pengembangan—sangat mudah: Berkomitmen ke main, sebarkan perubahan Anda dan uji dalam staging hingga siap, lalu menyebarkan ke produksi.

Sebagai langkah terakhir, pilihlah komit Anda dari main untuk dikembangkan untuk memastikan rilis berikutnya akan berisi semua perbaikan. Jika Anda berakhir dengan beberapa komit perbaikan terbaru, Anda menghemat tenaga—terutama jika IDE Anda atau alat Git lainnya dapat memfasilitasinya—dengan membuat dan menerapkan tambalan alih-alih memetik ceri beberapa kali. Mencoba melakukan squash merge main to develop setelah rilis awal kemungkinan akan berakhir dengan konflik dengan kemajuan independen yang dibuat di cabang develop, jadi saya tidak menyarankan itu.

Menangani hotfix selama rilis aktif —yaitu, ketika Anda baru saja mendorong main dan masih mempersiapkan rilis baru—adalah bagian terlemah dari aliran Git yang ditingkatkan. Bergantung pada panjang siklus rilis dan tingkat keparahan masalah yang harus Anda selesaikan, selalu usahakan untuk menyertakan perbaikan dalam rilis baru itu sendiri—itulah cara termudah untuk dilakukan, dan tidak akan mengganggu keseluruhan alur kerja sama sekali.

Jika itu tidak boleh dilakukan—Anda harus memperkenalkan perbaikan dengan cepat, dan Anda tidak sabar menunggu rilis baru bersiap-siap—lalu bersiaplah untuk prosedur Git yang agak rumit:

  1. Buat cabang—kami akan menyebutnya “rilis baru”, tetapi tim Anda dapat mengadopsi konvensi penamaan apa pun di sini—pada komit yang sama dengan tip main. Dorong rilis baru.
  2. Hapus dan buat ulang cabang utama lokal di komit tag yang Anda buat sebelumnya untuk rilis aktif saat ini. Dorong paksa utama.
  3. Perkenalkan perbaikan yang diperlukan untuk main, deploy ke lingkungan staging, dan uji. Kapan pun itu siap, terapkan ke produksi.
  4. Menyebarkan perubahan dari main saat ini ke rilis baru baik melalui cherry-picking atau patch.
  5. Setelah itu, ulangi prosedur rilis: Beri tag pada ujung main saat ini dan dorong tag, hapus dan buat ulang main lokal di ujung cabang rilis baru, dan tekan paksa main.
    1. Anda mungkin tidak memerlukan tag sebelumnya, jadi Anda dapat menghapusnya.
    2. Cabang rilis baru sekarang berlebihan, jadi Anda juga dapat menghapusnya.
  6. Anda sekarang harus baik untuk pergi seperti biasa dengan rilis baru. Selesaikan dengan menyebarkan hotfix darurat dari main ke develop melalui cherry-picking atau patch.

Grafik komit Git saat berubah saat melakukan perbaikan terbaru selama rilis aktif di bawah aliran Git yang ditingkatkan. Grafik awal telah berkembang sebagai garis komitmen terpanjang, dengan main divergen dua commit sebelumnya oleh satu commit, dan tiga commit sebelumnya, cabang a menyimpang oleh satu commit, ditandai v2020-09-18. Setelah dua langkah pertama di atas, grafik kemudian memiliki rilis baru di mana main dulu, dan main tidak genap dengan v2020-09-18. Langkah selanjutnya dilakukan, menghasilkan grafik akhir, di mana main adalah komit di depan rilis baru, dan v2020-09-20 adalah komit di depan v2020-09-18.

Dengan perencanaan yang tepat, kualitas kode yang cukup tinggi, dan pengembangan yang sehat serta budaya QA, kecil kemungkinan tim Anda harus menggunakan metode ini. Adalah bijaksana untuk mengembangkan dan menguji rencana bencana seperti itu untuk meningkatkan aliran Git, untuk berjaga-jaga—tetapi saya tidak pernah perlu menggunakannya dalam praktik.

Pengaturan CI/CD di Atas Aliran Git yang Ditingkatkan

Tidak setiap proyek membutuhkan lingkungan pengembangan khusus. Mungkin cukup mudah untuk menyiapkan lingkungan pengembangan lokal yang canggih di setiap mesin pengembang.

Tetapi lingkungan pengembangan yang berdedikasi dapat berkontribusi terhadap budaya pembangunan yang lebih sehat. Menjalankan tes, mengukur cakupan tes, dan menghitung metrik kompleksitas pada cabang pengembangan sering kali mengurangi biaya kesalahan dengan menangkapnya dengan baik sebelum berakhir di staging.

Saya menemukan beberapa pola CI/CD sangat berguna ketika dikombinasikan dengan aliran Git yang ditingkatkan:

  • Jika Anda memerlukan lingkungan pengembangan, siapkan CI untuk membangun, menguji, dan menerapkannya pada setiap komit ke cabang pengembangan. Cocokkan dalam pengujian E2E di sini juga, jika Anda memilikinya dan jika itu masuk akal dalam kasus Anda.
  • Siapkan CI untuk membangun, menguji, dan menerapkan ke lingkungan staging pada setiap komit ke cabang utama. Pengujian E2E juga cukup bermanfaat pada saat ini.
    • Mungkin tampak berlebihan untuk menggunakan pengujian E2E di kedua tempat, tetapi ingat bahwa perbaikan terbaru tidak akan terjadi dalam pengembangan. Memicu E2E pada komit ke main akan menguji hotfix dan perubahan sehari-hari sebelum mereka keluar, tetapi juga memicu komit untuk mengembangkan akan menangkap bug lebih awal.
  • Konfigurasikan CI dengan cara yang memungkinkan tim Anda menerapkan build dari lingkungan utama ke produksi berdasarkan permintaan manual.

Pengaturan CI/CD yang direkomendasikan dengan aliran Git yang ditingkatkan ketika ada lingkungan pengembangan ("dev") selain staging ("stage") dan produksi ("prod"). Semua komit pada cabang pengembangan menghasilkan build yang di-deploy ke dev. Demikian juga, semua commit ke hasil utama dalam build yang di-deploy ke stage. Permintaan manual dari commit tertentu dari hasil utama dalam build yang diterapkan ke produksi.

Pola seperti itu relatif sederhana, namun menyediakan mesin yang kuat untuk mendukung operasi pengembangan sehari-hari.

Model Aliran Git yang Ditingkatkan: Peningkatan dan Kemungkinan Batasan

Aliran Git yang ditingkatkan bukan untuk semua orang. Itu memanfaatkan taktik kekuatan kontroversial yang mendorong cabang utama, sehingga puritan mungkin membencinya. Dari sudut pandang praktis, tidak ada yang salah dengan itu.

Seperti disebutkan, perbaikan terbaru lebih menantang selama rilis tetapi masih memungkinkan. Dengan perhatian yang tepat pada QA, cakupan pengujian, dll. yang seharusnya tidak terjadi terlalu sering, jadi dari sudut pandang saya, ini adalah pertukaran yang valid untuk manfaat keseluruhan dari aliran Git yang ditingkatkan dibandingkan dengan aliran Git klasik. Saya akan sangat tertarik untuk mendengar bagaimana peningkatan tarif aliran Git dalam tim yang lebih besar dan dengan proyek yang lebih kompleks, di mana perbaikan terbaru mungkin lebih sering terjadi.

Pengalaman positif saya dengan model aliran Git yang disempurnakan juga sebagian besar berkisar pada proyek komersial sumber tertutup. Ini mungkin bermasalah untuk proyek sumber terbuka di mana permintaan tarik sering didasarkan pada turunan rilis lama dari pohon sumber. Tidak ada hambatan teknis untuk menyelesaikannya—hanya mungkin membutuhkan lebih banyak usaha daripada yang diharapkan. Saya menyambut umpan balik dari pembaca dengan banyak pengalaman di ruang sumber terbuka mengenai penerapan aliran Git yang ditingkatkan dalam kasus seperti itu.

Terima kasih khusus kepada rekan Toptal Antoine Pham atas peran kuncinya dalam mengembangkan ide di balik peningkatan aliran Git.


Bacaan Lebih Lanjut di Blog Teknik Toptal:

  • Pengembangan Berbasis Batang vs. Aliran Git
  • Alur Kerja Git untuk Pro: Panduan Git yang Baik

Lencana Mitra Emas Microsoft.

Sebagai Mitra Emas Microsoft, Toptal adalah jaringan elit pakar Microsoft Anda. Bangun tim berkinerja tinggi dengan para ahli yang Anda butuhkan - di mana pun dan kapan pun Anda membutuhkannya!