DEV Community

Akhmad
Akhmad

Posted on

Muvaffaqiyatli Git filialash modeli (A successful Git branching model)

Intro

Ushbu maqolada men turli loyihalarni ishlab chiqish jarayonida tadbiq qilsa bo'ladigan rivojlanish modelini yoritib beraman. Aynan ushbu modelni qo'llashdan oldin judayam ko'plab noqulaylik va muammolarga duch kelgan edim. Ushbu maqolani birqancha resurslardan olgan firklarim va ozgina to'plagan tajribam asosida yozishga qaror qildim. Bu maqola sizga tarmoqlanish strategiyasi (branching strategy) va relizlarni boshqarish (release management) masalalarida foydali bo'ladi degan umiddaman.

Image

Git va Nima uchun Git ?

Gitning boshqa tizimlarga nisbatan farqlarini batafsil ma'lumotlar yetarlicha shu sababdan bu mavzuga batafsil to'xtalmayman. Ammo gitni boshqa alternativ VCS vositalaridan afzal ko'raman. Ushbu tizim bir qancha ishlab chiqaruvchilar ishini birlashtira oladigan eng yaxshi tizim. Shu bilan birga git bilan bu jarayon juda sodda va oson. Git haqida asosiy ma'lumotlar 1-3 bo'limlarda yortilgan. Undan tashqari ushbu mavzuga aloqador boshqa ko'plab resurslar topishingiz.
Men foydalangan va foydalanadigan manbalarni post ohirida qoldiraman!
Qo'shimcha sifatida ayta olamanki Gitda branching va merging amaliyotlari juda ham oson tadbiq qilingan. Versiyani boshqarish vositalari hamma narsadan ko'ra ko'proq tarmoqlanish/birlashishda yordam berishi kerak.

Keling, ishlab chiqish modeliga o'taylik. Men bu erda taqdim etmoqchi bo'lgan model, aslida, boshqariladigan dasturiy ta'minotni ishlab chiqish jarayoniga kelish uchun har bir jamoa a'zosi amal qilishi kerak bo'lgan protseduralar to'plamidan iborat.

Asosiy filiallar (The main branches)

Eng asosiysi ushbu rivojlanish modeliga ko'ra markaziy repositoryda cheksiz umrga ega 2ta filial bo'lishi kerak

  • master or main
  • develop or dev

master branch har bir Git foydalanuvchisi uchun tanish bo'lishi kerak. Asosiy branchga paralell ravishta dev deb nomlangan branch bo'lishi kerak. origin/masterda mavjud bo'lgan HEAD manba kodini (source code) productionga tayyor deb hisoblaymiz.

origin/developda mavjud bo'lgan so'ngi HEAD manba kodi (source code) keyingi taqdimot (production|relase) uchun ohirgi ishlab chiqarish o'zgarishlari (development changes) holatni aks ettiradi. Bazilar buni "integration branch" deb atashadi. Bu yerda har qanday avtomatik buildlar sodir bo'ladi.

develop bo'limidagi manba kodi (source code) barqaror (stable) kelib tayyor bo'lganida barcha o'zgarishlar master branchga biriktirilishi (merge) va reliz uchun belgilanishi kerak. Bu jarayon birmuncha intensiv yondoshuvni ham talab etadi. Misol uchun relizlarni versiyalash ham mumkin. Barcha hali reliz qilinmagan o'zgarishlar ushbu branchga birlashadi.

Shuning uchun har safar o'zgarishlar masterga birlashtirilganda by yangi nashr (relase) ekanini anglatadi. Biz ushbu masalaga jiddiy qarashimiz lozim. Dasturiy ta'minotni ishlab chiqish jarayonida yangi reliz uchun maksimal darajada ishonchli va barqaror bo'lishi kerak. Bu bizga loyihamiz sifatli bo'lishini ta'minlaydi.

Image

Qo'llab-quvvatlovchi filiallar (Supporting branches)

Asosiy filiallar master va develop bilan bir qatorda bizning rivojlanish modelimiz jamoa a'zolari o'rtasida paralell rivojlanishga yordam berish, yangilanishlarni kuzatishni onsonlashtirish, relizlardan keyingi chiqgan muammolarni tuzatishga yordam berish uchun turli yordamchi branchlardan foydalaniladi. Asosiy branchlardan farli o'laroq ushbu branchlar vaqtinchalik xisoblanadi chunki ular kerakli ishlar yakunlangach olib tashlanadi.

Biz foydalanishimiz mumkin bo'lgan har xil turdagi branchlar:

  • Feature branches (Yangi xususiyatlar)
  • Release branches (Relizlar)
  • Hotfix branches (Relizda chiqgan xatolarni tuzatish uchun)

Ushbu filiallarning har biri o'ziga xos maqsadga ega va qaysi filiallar ularning boshlang'ich filiali bo'lishi mumkinligi va qaysi filiallar ularni birlashtirish maqsadlari bo'lishi kerakligi haqidagi qat'iy qoidalarga bog'liq.

Hech qanday holatda bu filiallar texnik nuqtai nazardan "maxsus" emas. Filial turlari biz ulardan qanday foydalanishimizga qarab tasniflanadi. Ular, albatta, oddiy eski Git branchlari. Shunchaki semantik nuqtai nazardan qarash to'g'ri bo'ladi.

Xususiyatli filiallar (Feature branches)

Quyidagidan bo'linishi mumkin:
develop
Qayta birlashishi kerak:
develop

Filial nomlash qoidalari (branch naming convention):
Barcha nomlar faqat quyidagilardan tashqari master, develop, release-*, hotfix-*

Xususiyat (feature) yoki biror imkoniyat branchlari (bazan topic branch deb ataladi chunki biror imkoniyat nomi bilan nomlanishi mumkin masalan authentication yoki auth-feauture) yaqin yoki uzoq kelajakdagi versiya uchun yangi imkoniyatlarni ishlab chiqish uchun ishlatiladi. Imkoniyatni ishlab chiqish boshlanganda ushbu imkoniyat birlashtiriladigan versiya xozircha nomalum bo'lishi mumkin. Xususiyat yoki imkoniyat (feauture) branchining mohiyati shundaki, u xusisiyat ishlab chiqarilgunga qadar mavjud bo'ladi lekin oxir-oqibat developga qayta birlashadi (biror ishlab chiqilgan xususiyatni ma'lum versiyaga qo'shish uchun) yoki o'chirib tashlanadi (xafagarchilik tug'diradigan tajriba bo'lsa).

Image

Xususiyat tarmoqlari odatda origin emas, faqat ishlab chiquvchi repolarida mavjud.

Xususiyat bo'limi yasash

Yangi xususiyat ustida ishlashni boshlaganingizda, develop bo'limidan (branch) ajralib chiqing.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
Enter fullscreen mode Exit fullscreen mode

Tugallangan xususiyatni develop branchiga birlashtirish (merge)

Yakunlangan xususiyatlar ularni kelgusi relizga qo'shish uchun ishlab chiqish bo'limiga birlashtirilishi mumkin:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop
Enter fullscreen mode Exit fullscreen mode

--no-ff bayrog'i birlashma har doim yangi topshiriq ob'ektini yaratishga olib keladi, xatto birlashtirish oldinga siljish bilan amalga oshirilishi mumkin bo'lsa ham. Bu xususiyat filialining tarixiy mavjudligi haqidagi ma'lumotni yo'qotib qo'ymaydi va ushbu xususiyatni birgalikda qo'shgan barcha majburiyatlarni birgalikda guruhlaydi. Quyidagi rasmni ko'ring:

Image

Ikkinchi holda, Git tarixidan ob'ektlarning qaysi biri birgalikda xususiyatni amalga oshirganligini ko'rishning iloji yo'q - barcha jurnal xabarlarini qo'lda o'qish kerak bo'ladi. Butun xususiyatni (ya'ni, bir guruh majburiyatlarni) qaytarish oxirgi vaziyatda haqiqiy bosh og'rig'idir, holbuki --no-ff bayrog'i ishlatilsa, buni osonlikcha bajarish mumkin.

Ha, u yana bir nechta (bo'sh) ob'ektlarni yasaydi, foydasi zararidan katta.

Reliz branchlari (Release branches)

Quyidagidan bo'linishi mumkin:
develop
Qayta birlashishi kerak:
develop va master
Filial nomlash qoidalari:
relase-*

Reliz branchlari yangi reliz nashrini (new production relase) tayyorlashni qo'llab-quvvatlaydi. Bundan tashqari, ular kichik xatolarni tuzatishga va meta-ma'lumotlarni relizlar uchun tayyorlashga imkon beradi (versiya raqami, tuzilish sanalari va boshqalar). Ushbu barcha ishlarni reliz bo'limida bajarish orqali ishlab chiqish bo'limi (develop branch) keyingi katta versiya uchun xususiyatlarni olish uchun tozalanadi.

Yangi versiyani develop branchdan ajratishning asosiy maqsadi ishlab chiqarish jarayonida aynan ma'lum relizda qilinishi kerak bo'lgan imkoniyatlar yoki tuzatish ishlarini aynan shu relizga bog'lab uni ishlab chiqarish bilan ham birlashtirishdan iborat. Kelajakdagi versiyalarga mo'ljallangan barcha xususiyatlar bo'lmasligi mumkin - ular relizlar tarmog'i bo'linmaguncha kutishlari kerak.

Aynan relizlar bo'limining boshida bo'lajak versiyaga versiya raqami beriladi . O'sha paytgacha ishlab chiqish bo'limi "keyingi versiya" uchun o'zgarishlarni aks ettirdi, ammo bu "keyingi reliz" oxir-oqibat 0,3 yoki 1,0 bo'ladimi, toki reliz bo'limi ishga tushirilgunga qadar noma'lum. Ushbu qaror relizlar bo'limining boshlanishi bilan qabul qilinadi va loyihaning versiya raqamini buzish qoidalari bilan amalga oshiriladi.

Reliz branchini yasash (Creating a release branch)

Reliz branchlari ishlab chiqish (develop) branchidan yasaladi. Misol uchun, 1.1.5 versiyasi joriy ishlab chiqarish versiyasidir va bizda katta reliz bor. Rivojlanish holati “keyingi versiya”ga tayyor va biz bu versiya 1.2 (1.1.6 yoki 2.0 oʻrniga) boʻlishiga qaror qildik. Shunday qilib, biz filialni ajratamiz va reliz branchiga yangi versiya raqamini aks ettiruvchi nom beramiz:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)
Enter fullscreen mode Exit fullscreen mode

Yangi branchni yasab, unga o'tgandan so'ng, biz versiya raqamini ko'ramiz. Bu yerda bump-version.sh yangi versiyani aks ettirish uchun ishchi nusxadagi ba'zi fayllarni o'zgartiradigan xayoliy qobiq skript. (Bu albatta qo'lda o'zgartirish bo'lishi mumkin - bu ba'zi fayllarning o'zgarishidir. Bizning holatda ushbu jarayoni avtomatlashtirib qo'yilgan deb tassavur qilamiz. Jarayon abstakt bo'lgani uchun skript fayl misolida keltirildi) Keyin, buzilgan versiya raqami amalga oshiriladi.

Bu yangi branch albatta chiqarilgunga qadar bir muddat mavjud bo'lishi mumkin. Bu vaqt ichida xatolarni tuzatishlar ushbu branchda qo'llanilishi mumkin (ishlab chiqish develop branchda emas). Bu yerda yangi katta funksiyalarni qo'shish qat'iyan man etiladi. Ular ishlab chiqishga birlashtirilishi kerak agar katta funksionallar qo'shilishi kerak bo'lsa bularni keying relizga o'tkazish kerak bo'ladi.

Reliz branchni tugatish (Finishing a release branch).

Reliz branchning holati haqiqiy reliz bo'lishga tayyor bo'lganda ba'zi harakatlarni bajarish kerak. Birinchidan, reliz filiali masterga birlashtiriladi (chunki masterdagi har bir topshiriq ta'rifi bo'yicha yangi relizdir, esda tuting). Keyinchalik, ushbu tarixiy versiyaga kelajakda oson murojaat qilish uchun master bo'yicha ushbu majburiyat belgilanishi kerak. Va nihoyat, relizlar bo'limiga kiritilgan o'zgarishlarni ishlab chiqishda qayta birlashtirish kerak, shunda kelajakdagi productionlarda ham ushbu xatolar tuzatiladi.

Gitdagi dastlabki ikki qadam:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2
Enter fullscreen mode Exit fullscreen mode

Chiqarish tugallandi va kelajakda foydalanish uchun belgilandi.

Tahrirlash: Tegingizni kriptografik tarzda imzolash uchun -s yoki -u <key> bayroqlaridan foydalanishningiz ham mumkin.
Enter fullscreen mode Exit fullscreen mode

Reliz branchida kiritilgan o'zgarishlarni saqlab qolish uchun biz ularni qayta ishlab chiqishga (develop) birlashtirishimiz (merge) kerak. Gitda:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
Enter fullscreen mode Exit fullscreen mode

Ushbu qadam birlashma mojarosiga (merge conflict) olib kelishi mumkin (ehtimol xatto versiya raqamini o'zgartirganimiz uchun). Agar shunday bo'lsa, uni tuzating va majburiyatni bajaring.

Endi biz haqiqatan ham tayyormiz va reliz filiali olib tashlanishi mumkin, chunki bizga endi kerak emas:

$ git branch -d release-1.2
Enter fullscreen mode Exit fullscreen mode

Tuzatish filiallari (Hotfix branches)

Quyidagidan bo'linishi mumkin:
master
Qayta birlashishi kerak:
develop va master
Filial nomlash qoidalari:
hotfix-*

Tuzatish branchlari reliz branchlarga juda o'xshaydi chunki ular rejalashtirilmagan bo'lsa ham yangi ishlab chiqarish relizlariga tayyorgarlik ko'rish uchun mo'ljallangan. Ular jonli ishlab chiqarish versiyasining istalmagan holatiga darhol harakat qilish zaruratidan kelib chiqadi. Ishlab chiqarish versiyasidagi muhim xatolik darhol hal qilinishi kerak bo'lsa, tuzatish filiali ishlab chiqarish versiyasini belgilaydigan asosiy filialdagi tegishli tegdan ajratilishi mumkin.

Mohiyat shundan iboratki, jamoa a'zolarining ishi (rivojlanish bo'limida) davom etishi mumkin, boshqa bir kishi esa tezkor ishlab chiqarishni tuzatishni tayyorlamoqda.

Tuzatish branchini yasash (Creating the hotfix branch)

Tuzatish branchlari master branchdan yasalgan. Misol uchun, aytaylik, 1.2 versiyasi jonli ishlayotgan va jiddiy xato tufayli muammolarni keltirib chiqaradigan joriy ishlab chiqarish versiyasidir. Ammo rivojlanishdagi o'zgarishlar hali ham barqaror emas. Keyin tuzatish filialini ajratib, muammoni hal qilishni boshlashimiz mumkin:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)
Enter fullscreen mode Exit fullscreen mode

Tarqalgandan keyin versiya raqamini ko'rsatishni unutmang!

Keyin xatoni tuzating va tuzatishni bir yoki bir nechta alohida topshiriqlarda (commit) bajaring.

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)
Enter fullscreen mode Exit fullscreen mode

Tuzatish branchini yakunlash (Finishing a hotfix branch)

Tugallangach, xato tuzatish (hotfix) yana masterga birlashtirilishi (merge) kerak, lekin xato tuzatish keyingi versiyaga ham kiritilishini taʼminlash uchun uni yana ishlab chiqishga birlashtirish kerak. Bu reliz branchlari qanday tugaganiga to'liq o'xshaydi.

Birinchidan, masterni yangilang va relizni belgilang.

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1
Enter fullscreen mode Exit fullscreen mode
Tahrirlash: Tegingizni kriptografik tarzda imzolash uchun -s yoki -u <key> bayroqlaridan foydalanishningiz ham mumkin.
Enter fullscreen mode Exit fullscreen mode

Keyinchalik, ishlab chiqishda develop xato tuzatishni ham kiriting:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
Enter fullscreen mode Exit fullscreen mode

Bu yerdagi qoidadan bitta istisno shundaki agar hozirda reliz branch mavjud bo'lsa tuzatish o'zgarishlarini ishlab chiqish develop o'rniga o'sha reliz bo'limiga birlashtirish kerak. Tuzatishning reliz bo'limiga qayta birlashtirilishi oxir-oqibat reliz bo'limi tugagach xato tuzatuvchining ham ishlab chiqishga birlashishiga olib keladi. (Agar ishlab chiqishda ish shu zahotiyoq xatoni tuzatishni talab qilsa va reliz bo'limi tugashini kutmasa xato tuzatishni hozirda ishlab chiqishga xavfsiz tarzda birlashtirishingiz mumkin.)

Nihoyat vaqtinchalik branchni olib tashlang:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).
Enter fullscreen mode Exit fullscreen mode

Image

Latest comments (1)

Collapse
 
habibovulugbek profile image
HabibovUlugbek

Good job . Juda kerakli endi boshlaganlarga