Git Branching အခြေခံ

တခြား developer တွေနဲ့ကောင်းကောင်း collaborate လုပ်နိုင်ဖို့ Git Branching ကိုအခြေခံလောက်တော့ လေ့လာထားဖို့ လိုလိမ့်မယ်။ Git repository တခုကို commit တွေစုထားတဲ့ သေတ္တာတခုအဖြစ် မြင်ကြည့်လိုက်ရင် commit တခုစီတိုင်းမှာ ရှေ့က commit ကိုရည်ညွှန်းတဲ့ parent reference pointer ပါတယ်။ ဥပမာ commit A <= commit B <= commit C ဆိုပါတော့။ commit A က B ရဲ့ parent commit ဖြစ်ပြီး B ကတော့ C ရဲ့ parent commit ဖြစ်တယ်။ Commit ဆိုတာက version တခုကနေ ဖိုင်တွေ လိုအပ်သလို အသစ်ထည့်၊ ရှိပြီးသား code တွေပြင်၊ နောက် မလိုတာတွေ ဖျက်လိုက်ပြီး ရလာတဲ့ အခြေအနေကို နောက်ထပ် version တခုအဖြစ် သိမ်းလိုက်တာပဲ။ ဒါကို commit လို့ခေါ်တယ်။

Software Development လုပ်တဲ့အခါ team မန်ဘာကိုယ်စီက parallel သွားနိုင်ဖို့ သိပ်အရေးကြီးတယ်။ ဆိုလိုချင်တာက တယောက်​က code အဟောင်းမှာ bug တွေပြင်နေတုန်း နောက် developer တယောက်က feature အသစ် ဆက်ရေးနေနိုင်ဖို့​လိုတယ်။ ထိုင်စောင့်နေလို့မရဘူး။ ဒါမှ productive ဖြစ်မယ်။

Git ကဒီအတွက် ဘာနဲ့ support လဲဆိုရင် သူ့မှာ branch ဆိုတဲ့ concept ရှိတယ်။ branch မှာအရေးကြီးဆုံး metadata က HEAD pointer ပဲ။ အဲဒီ pointer ကို variable တခုလို့မြင်ကြည့်လို့ရတယ်။ main branch ကို commit A <= commit B <= commit C ဆိုပြီး commit 3 ခုနဲ့ ဖွဲ့စည်းထားတယ် ဆိုပါတော့။ main ရဲ့ Head က commit C ပဲ။ main's Head = C ပေါ့။

တကယ်လို့ ကိုယ်က bug ပြင်စရာရှိလို့ bug_fix ဆိုပြီးတော့ branch အသစ်တခုဆောက်လိုက်ရင် bug_fix's Head က C ဖြစ်လာတယ်။ အဲဒီကနေ ပြင်စရာရှိတဲ့ ဖိုင်တွေပြင်၊ အသစ်ထည့်စရာရှိတာတွေထည့်ပြီး version/commit အသစ်တခု လုပ်လိုက်တယ်။ commit D ပဲဆိုပါတော့။ ဒါဆို bug_fix ရဲ့ Head က D ဖြစ်သွားပြီ။ ဆိုလိုချင်တာက bug_fix က main ထက် commit တခုပိုစောနေမယ်။

... <= commit D <- bug_fix's HEAD

... <= commit C <- main's HEAD

ဒါက branch တွေရဲ့ အရိုးရှင်းဆုံး အ​​ခြေခံသဘော။

အဲဒီတော့ branch တွေကို ဘယ်လိုသုံးမလဲဆိုတဲ့ မေးခွန်းက အရေးကြီးလာတယ်။ အရှင်းဆုံးနည်းက stable branch တခုတည်းထားလိုက်တာပဲ။ ပြောရရင် main branch ပေါ့လေ။ bug fix တွေ new feature တွေရေးစရာရှိရင် main branch ကနေ branch အသစ်လေးတွေ ခွဲလိုက်။ ပြီးရင် ပြန်ပေါင်း။ ဒါပြီးရင် branch ခွဲတွေကို ဖျက်။ ဒါဆို long lived branch က main တခုတည်းရှိမယ်။ ကျန်တာတွေက ယာယီ (short lived) တွေချည်းပေါ့။ သုံးရတာ ရှင်းတယ်။ CI/CD (Continous Delivery) မှာဒီပုံစံအတွက် automation setup ကအလွယ်ဆုံးလို့တောင် ပြောလို့ရတယ်။ ဒါပေမယ့် သတိထားရမယ့်တချက်က main ထဲရောက်လာသမျှက deployment ready ဖြစ်ရမယ်။ တဝက်တပျက် commit တွေဖြစ်လို့မရဘူး။ အဲတော့ကာ main ထဲကိုမ merge ထည့်ခင် stable ဖြစ်ရဲ့လားစစ်ဖို့အတွက် test တွေကောင်းကောင်း ရှိရမယ်။

တကယ်လို့ကိုယ့် team ကခုလို main branch ထဲကို stable commit တွေချည်း ထည့်ဖို့ အဆင်မပြေဘူးဆိုရင် ကြားထဲ integration branch ထားတဲ့စတိုင်ကျင့်သုံးလို့ရတယ်။ ဒီပုံစံမှာ feature နဲ့ bug fix branch တွေကို review လုပ်မယ် test တွေစစ်မယ်။ အဲဒါပြီးရင် main ထဲတန်းမ merge သေးပဲ စောင့်ဦးမယ်။ pause တယ်ပေါ့။ deploy လုပ်ချင်ပြီဆိုတဲ့အခါကျမှ main ကနေ integration branch ခွဲထုတ်လိုက်ပြီး စောစောက စောင့်နေတဲ့ ready branch တွေကို တခုချင်း ဒါမှမဟုတ် batch လိုက် merge ထည့်မယ်။ deploy မယ်ပေါ့။

error မတက်ဘူးဆိုရင် integration ထဲကဟာတွေ main ထဲကို merge မယ်။ တကယ်လို့ error တက်တယ်ဆိုလည်း ရှေ့ main ကိုချက်ချင်း rollback လို့ရတယ်။ (Btw, Integration branch မထားချင်ဘူးဆိုရင်လည်း feature branch တွေကို တိုက်ရိုက် deploy လို့ရတယ် အိုင်ဒီယာကတော့ အတူတူပဲ) နည်းနည်းလေး ပိုရှုပ်သွားတာတခုက branch author တွေအနေနဲ့ စောင့်နေရတဲ့အချိန်မှာ main branch နဲ့လိုက် up to date ဖြစ်အောင် maintain လုပ်နေဖို့ လိုအပ်လိမ့်မယ်။ နို့မို့ဆို integration phase ဒါမှမဟုတ် main ထဲပြန်အထည့်မှာ merge conflict တွေ ဖြစ်လိမ့်မယ်။

အခု ပြောသွားတဲ့ နှစ်မျိုးအပြင် GitFlow ဆိုတဲ့ branching စတိုင်ရှိသေးတယ်။ အသုံးလည်းများတယ်။ ဒီပုံစံ​မှာ main အပြင် long lived branch နောက်ထပ်တခု develop ဆိုတာရှိတယ်။ develop branch ထဲ feature တွေလာ merge ရင်း အချိန်တခုမှာ feature freeze ပြီဆိုပြီး ကြေညာလိုက်မယ်။ အဲဒီ freeze လိုက်တဲ့အချိန်ကစပြီး develop ကနေ release branch တခုခွဲလိုက်တယ်။ release branch ကို test တယ်။ bug တွေတွေ့ရင် branch ထပ်ခွဲပြီးဖြစ်ဖြစ် မခွဲပဲဖြစ်ဖြစ် fix တယ်။ fix လိုက်တာတွေကို develop branch ထဲပြန် merge တယ်။ ဒါပေမယ့် develop branch ထဲနောက်ထပ် ဆက်ရေးနေတာတွေကိုတော့ release ထဲကို vice versa ပြန်မ merge ဘူးပေါ့။

နောက်ဆုံး release မှာ bug တွေကုန်ပြီဆိုရင် sematic tag ပြီး ဥပမာ v1.0.0 ဆိုပြီး main ထဲကို merge ပလိုက်တယ်။ တကယ်လို့ အဲကျမှ bug ထပ်ထည့်တွေ့ရင် urgent fix (hot fix) branch ခွဲပြီး ချက်ချင်းပြင်တယ်။ ပြင်လို့ ရလာတဲ့ဟာကို main ထဲ v1.0.1 လို့ tag ပြီးပြန် merge တယ်။ ပြီးတော့ develop ထဲကိုလည်း merge တယ်။ ဒီပုံစံမှာ မကောင်းတဲ့အချက်က automate ဖို့အတွက် သိပ်ပြီးအဓိပ္ပါယ်ရှိမနေတာပဲ။ feature freeze တယ်၊ မ freeze ဘူးဆိုတာ လူက ဆုံးဖြတ်တာဖြစ်သလို release ထွက်မယ်ဆိုတာကိုလည်း လူကပဲမီးစိမ်းပြရတာဖြစ်တယ်။ ပြီးတော့ branch မှား clone မိ develop လုပ်မိရင်လည်း ရှင်းရမှာ မချောင်ဘူး။

ဒီနေ့ခေတ်နဲ့လည်းညီမယ်၊ CI/CD နဲ့လည်း တော်တော်လေး အံဝင်တဲ့နည်းကတော့ အခု ပြောသွားတာတွေကို နည်းနည်းစီ ယူထားတဲ့ GTF (Git Tag Flow) ပဲ။ GTF လည်း tag တွေသုံးပါတယ်။ ဒါပေမယ့်ဘယ် code က ဘယ် environment ကိုသွားမှာဆိုတဲ့ context aware tag တွေသုံးတယ်။ CI/CD pipeline ဆင်တဲ့အခါ အဲဒီဟာလေးတွေကို သေချာလေ့လာရမယ်။