Version Control နှင့် Git

Version control systems (VCSs) ဆိုသည်မှာ source code များ (သို့မဟုတ် အခြား ဖိုင်နှင့် ဖိုဒါ စုစည်းမှုများ) ၏ ပြောင်းလဲမှုများကို စောင့်ကြည့်မှတ်တမ်းတင်ရန် အသုံးပြုသော tools များ ဖြစ်ကြသည်။ အမည်တွင် ပါရှိသည့်အတိုင်း ဤ tools များသည် ပြောင်းလဲမှု မှတ်တမ်း (history) ကို ထိန်းသိမ်းထားနိုင်ရန် ကူညီပေးရုံမျှမက ပူးပေါင်းဆောင်ရွက်မှုကိုလည်း ပိုမိုလွယ်ကူ စေသည်။ လောဂျစ်အားဖြင့် VCS များသည် ဖိုဒါတစ်ခုနှင့် ၎င်း၏ ပါဝင်သည့်အရာများ၏ ပြောင်းလဲမှုများကို snapshots စီးရီးအဖြစ် စောင့်ကြည့် မှတ်တမ်းတင်ပေးပြီး၊ snapshot တစ်ခုစီသည် ပင်မ directory အတွင်းရှိ ဖိုင်များ/ဖိုဒါများ၏ စုစုပေါင်း အခြေအနေကို ပေါင်းစည်း သိမ်းဆည်းထားသည်။ ထို့အပြင် VCS များသည် snapshot တစ်ခုစီကို မည်သူဖန်တီးခဲ့သည်၊ snapshot တစ်ခုစီနှင့် သက်ဆိုင်သည့် မက်ဆေ့ဂျ်များ စသည့် metadata များကိုလည်း ထိန်းသိမ်းထားပေးသည်။

Version control သည် အဘယ်ကြောင့် အသုံးဝင်သနည်း။ သင်တစ်ဦးတည်း အလုပ်လုပ်နေချိန်တွင်ပင် ပရောဂျက်၏ ယခင် snapshot များကို ပြန်ကြည့်နိုင်ခြင်း၊ အချို့သော ပြောင်းလဲမှုများကို အဘယ်ကြောင့် ပြုလုပ်ခဲ့သည်ကို မှတ်တမ်းတင်ထားနိုင်ခြင်း၊ ပြိုင်တူ ဖွံ့ဖြိုးတိုးတက်ရေး branch များတွင် အလုပ်လုပ်နိုင်ခြင်းနှင့် အခြားအရာများစွာကို ပြုလုပ်နိုင်စေသည်။ အခြားသူများနှင့် ပူးပေါင်းလုပ်ဆောင်ရာတွင် အခြားသူများ မည်သည့်အရာများ ပြောင်းလဲထားသည်ကို ကြည့်ရှုရန်နှင့် ပြိုင်တူ လုပ်ဆောင်ရာတွင် ဖြစ်ပေါ်လာသည့် ပဋိပက္ခများ (conflicts) ကို ဖြေရှင်းရန်အတွက် အလွန်တန်ဖိုးရှိသော tool တစ်ခု ဖြစ်သည်။

ခေတ်မီ VCS များသည် အောက်ပါမေးခွန်းများကို လွယ်ကူစွာ (မကြာခဏဆိုသလို အလိုအလျောက်) ဖြေကြားနိုင်စေသည် -

အခြား VCS များလည်း ရှိသော်လည်း Git သည် version control အတွက် လက်တွေ့ကျကျ အဓိက စံနှုန်းတစ်ခု (de facto standard) ဖြစ်သည်။ ဤ XKCD comic တွင် Git ၏ ကျော်ကြားမှုကို သရုပ်ဖော်ထားသည် -

xkcd 1597

Git ၏ interface သည် leaky abstraction တစ်ခုဖြစ်သောကြောင့် Git ကို အထက်မှ အောက်သို့ (၎င်း၏ interface / command-line interface မှ စတင်၍) လေ့လာခြင်းသည် ရှုပ်ထွေးမှုများစွာကို ဖြစ်ပေါ်စေနိုင်သည်။ command အနည်းငယ်ကို အလွတ်ကျက်မှတ်ပြီး ဂါထာမန္တန်များကဲ့သို့ မှတ်ယူကာ တစ်ခုခု အမှားအယွင်းဖြစ်သည့်အခါတိုင်း အထက်ပါ ကာတွန်းထဲမှ နည်းလမ်းအတိုင်း လိုက်လုပ်နေမိနိုင်သည်။

Git တွင် ရုပ်ဆိုးသော interface တစ်ခု ရှိသည်ကို ဝန်ခံရမည်ဖြစ်သော်လည်း ၎င်း၏ နောက်ကွယ်မှ ဒီဇိုင်းနှင့် စိတ်ကူးများမှာ အလွန်လှပပါသည်။ ရုပ်ဆိုးသော interface ကို အလွတ်ကျက်မှတ် ရမည် ဖြစ်သော်လည်း၊ လှပသော ဒီဇိုင်းကိုမူ နားလည် သဘောပေါက် နိုင်ပါသည်။ ထို့ကြောင့် ကျွန်ုပ်တို့သည် Git ကို ၎င်း၏ data model မှ စတင်၍ အောက်မှ အထက်သို့ ရှင်းပြမည်ဖြစ်ပြီး နောက်ပိုင်းတွင်မှ command-line interface ကို လွှမ်းခြုံ ရှင်းပြသွားမည် ဖြစ်သည်။ Data model ကို နားလည်သွားပါက command များသည် အခြေခံ data model ကို မည်သို့ ပြုပြင်ပြောင်းလဲသည် ဆိုသည်ကို ပိုမိုကောင်းမွန်စွာ နားလည်နိုင်မည် ဖြစ်သည်။

Git ၏ data model

Git ၏ တီထွင်ဖန်တီးနိုင်စွမ်းသည် မှတ်တမ်း ထိန်းသိမ်းခြင်း၊ branch များကို ပံ့ပိုးပေးခြင်းနှင့် ပူးပေါင်းဆောင်ရွက်မှုကို ဖြစ်စေခြင်းကဲ့သို့သော version control ၏ ကောင်းမွန်သည့် စွမ်းဆောင်ရည် အားလုံးကို ဖြစ်ပေါ်စေသည့် သေချာစွာ စဉ်းစားထားသော ၎င်း၏ data model တွင် ရှိသည်။

Snapshots

Git သည် ပင်မ directory အတွင်းရှိ ဖိုင်များနှင့် ဖိုဒါများ စုစည်းမှု၏ မှတ်တမ်းကို snapshot စီးရီးတစ်ခုအဖြစ် ပုံစံထုတ် (model) ထားသည်။ Git ဝေါဟာရတွင် ဖိုင်တစ်ခုကို “blob” ဟု ခေါ်ပြီး ၎င်းသည် byte အစုအဝေးတစ်ခုမျှသာ ဖြစ်သည်။ Directory တစ်ခုကို “tree” ဟု ခေါ်ပြီး ၎င်းသည် အမည်များကို blobs သို့မဟုတ် trees များနှင့် ချိတ်ဆက်ပေးသည် (ထို့ကြောင့် directory များတွင် အခြား directory များ ပါဝင်နိုင်သည်)။ Snapshot သည် စောင့်ကြည့် စောင့်ရှောက်ခံနေရသည့် ထိပ်ဆုံးအဆင့် tree ဖြစ်သည်။ ဥပမာအားဖြင့် ကျွန်ုပ်တို့တွင် အောက်ပါအတိုင်း tree တစ်ခု ရှိနိုင်သည်။

<root> (tree)
|
+- foo (tree)
|  |
|  + bar.txt (blob, contents = "hello world")
|
+- baz.txt (blob, contents = "git is wonderful")

ထိပ်ဆုံးအဆင့် tree တွင် element နှစ်ခု ပါဝင်သည် - tree “foo” (၎င်းကိုယ်တိုင်၌ element တစ်ခုဖြစ်သော blob “bar.txt” ပါဝင်သည်) နှင့် blob “baz.txt” တို့ ဖြစ်ကြသည်။

မှတ်တမ်းကို ပုံစံထုတ်ခြင်း - Snapshots များကို ဆက်စပ်ခြင်း

Version control system တစ်ခုသည် snapshot များကို မည်သို့ ဆက်စပ်သင့်သနည်း။ ရိုးရှင်းသော ပုံစံတစ်ခုမှာ မျဉ်းဖြောင့်အတိုင်း သွားသော မှတ်တမ်း (linear history) ရှိခြင်း ဖြစ်သည်။ မှတ်တမ်းတစ်ခုသည် အချိန်အလိုက် စီထားသော snapshot များ၏ စာရင်းတစ်ခု ဖြစ်လိမ့်မည်။ အကြောင်းပြချက်များစွာကြောင့် Git သည် ဤကဲ့သို့ ရိုးရှင်းသော ပုံစံကို မသုံးပါ။

Git တွင် မှတ်တမ်းတစ်ခုသည် snapshots များ၏ directed acyclic graph (DAG) တစ်ခု ဖြစ်သည်။ ထိုစကားရပ်သည် ခန်းနားသော သင်္ချာဝေါဟာရတစ်ခုကဲ့သို့ ထင်ရနိုင်သော်လည်း မကြောက်ပါနှင့်။ ဤအရာ၏ အဓိပ္ပာယ်မှာ Git ရှိ snapshot တိုင်းသည် ၎င်း၏ ရှေ့တွင် ရှိခဲ့သော snapshot များ ဖြစ်သည့် “parents” အစုအဝေးကို ညွှန်းဆိုနေခြင်း ဖြစ်သည်။ snapshot တစ်ခုသည် ပြိုင်တူ လုပ်ဆောင်နေသော ဖွံ့ဖြိုးတိုးတက်ရေး branch နှစ်ခုကို ပေါင်းစည်းခြင်း (merging) ကဲ့သို့သော အကြောင်းရင်းများကြောင့် parent အများအပြားမှ ဆင်းသက်လာနိုင်သောကြောင့် (linear history တွင် ဖြစ်မည်ကဲ့သို့) parent တစ်ခုတည်း မဟုတ်ဘဲ parent အစုအဝေး ဖြစ်နေခြင်း ဖြစ်သည်။

Git သည် ဤ snapshots များကို “commit” များဟု ခေါ်သည်။ Commit history တစ်ခုကို အမြင်ပုံဖော်ကြည့်ပါက အောက်ပါအတိုင်း တွေ့ရပါလိမ့်မည် -

o <-- o <-- o <-- o
            ^
             \
              --- o <-- o

အထက်ပါ ASCII art တွင် o များသည် သီးခြား commit (snapshot) များကို ကိုယ်စားပြုသည်။ မြှားများသည် commit တစ်ခုစီ၏ parent ကို ညွှန်ပြသည် (“နောက်မှလာသည်” ဆက်ဆံရေး မဟုတ်ဘဲ “ရှေ့မှလာသည်” ဆက်ဆံရေး ဖြစ်သည်)။ တတိယမြောက် commit ပြီးနောက် မှတ်တမ်းသည် သီးခြား branch နှစ်ခုအဖြစ် ခွဲထွက်သွားသည်။ ၎င်းသည် ဥပမာအားဖြင့် သီးခြား feature နှစ်ခုကို တစ်ခုနှင့်တစ်ခု သီးခြားစီ ပြိုင်တူ ဖွံ့ဖြိုးတိုးတက်စေခြင်း ဖြစ်နိုင်သည်။ နောင်တွင် ဤ branch များကို ပေါင်းစည်းပြီး feature နှစ်ခုလုံး ပါဝင်သည့် snapshot သစ်တစ်ခု ဖန်တီးနိုင်သည်၊ ထိုအခါ အသစ်ဖန်တီးလိုက်သော merge commit ကို စာလုံးမည်းဖြင့် ပြသထားသည့် အောက်ပါအတိုင်း မှတ်တမ်းသစ်တစ်ခု ဖြစ်ပေါ်လာမည် -


o <-- o <-- o <-- o <---- o
            ^            /
             \          v
              --- o <-- o

Git ရှိ Commit များသည် ပြောင်းလဲ၍မရပါ (immutable)။ သို့သော် ဤသည်မှာ အမှားများကို ပြင်ဆင်၍ မရနိုင်ဟု အဓိပ္ပာယ်မရပါ၊ commit history ကို “ပြင်ဆင်ခြင်း” ဆိုသည်မှာ အမှန်တကယ်တွင် စာမျက်နှာသစ် commit အသစ်များကို ဖန်တီးလိုက်ခြင်းဖြစ်ပြီး ညွှန်းဆိုချက်များ (references - အောက်တွင် ကြည့်ပါ) ကို commit အသစ်များသို့ ညွှန်ပြရန် အပ်ဒိတ်လုပ်လိုက်ခြင်း ဖြစ်သည်။

Data model ကို Pseudocode အဖြစ် ကြည့်ခြင်း

Git ၏ data model ကို pseudocode ဖြင့် ရေးသားထားသည်ကို ကြည့်ရှုခြင်းသည် သင်ယူရန် အထောက်အကူဖြစ်စေနိုင်ပါသည် -

// a file is a bunch of bytes
type blob = array<byte>

// a directory contains named files and directories
type tree = map<string, tree | blob>

// a commit has parents, metadata, and the top-level tree
type commit = struct {
    parents: array<commit>
    author: string
    message: string
    snapshot: tree
}

၎င်းသည် သပ်ရပ်ပြီး ရိုးရှင်းသော မှတ်တမ်း ပုံစံတစ်ခု ဖြစ်သည်။

Objects နှင့် content-addressing

“object” ဆိုသည်မှာ blob၊ tree သို့မဟုတ် commit ဖြစ်သည် -

type object = blob | tree | commit

Git ၏ data store တွင် object အားလုံးကို ၎င်းတို့၏ SHA-1 hash ဖြင့် content-addressed လုပ်ထားသည်။

objects = map<string, object>

def store(object):
    id = sha1(object)
    objects[id] = object

def load(id):
    return objects[id]

Blobs၊ trees နှင့် commits များကို ဤနည်းဖြင့် ပေါင်းစည်းထားသည် - ၎င်းတို့အားလုံးသည် objects များ ဖြစ်ကြသည်။ ၎င်းတို့သည် အခြား object များကို ညွှန်းဆိုသည့်အခါ disk ပေါ်ရှိ ၎င်းတို့၏ ကိုယ်စားပြုမှုတွင် အမှန်တကယ် ပါဝင်နေခြင်း မဟုတ်ဘဲ ၎င်းတို့၏ hash ဖြင့် ညွှန်းဆိုချက်သာ ရှိကြသည်။

ဥပမာအားဖြင့် အထက်ပါ ဥပမာ directory ဖွဲ့စည်းပုံအတွက် tree သည် (git cat-file -p 698281bc680d1995c5f4caaf3359721a5a58d48d ကို အသုံးပြု၍ ကြည့်ရှုထားသည်) အောက်ပါအတိုင်း ဖြစ်သည် -

100644 blob 4448adbf7ecd394f42ae135bbeed9676e894af85    baz.txt
040000 tree c68d233a33c5c06e0340e4c224f0afca87c8ce87    foo

Tree ကိုယ်တိုင်တွင် ၎င်း၏ ပါဝင်သည့်အရာများဖြစ်သော baz.txt (blob) နှင့် foo (tree) သို့ ညွှန်ပြသည့် pointer များ ပါဝင်သည်။ git cat-file -p 4448adbf7ecd394f42ae135bbeed9676e894af85 ဖြင့် baz.txt နှင့် သက်ဆိုင်သော hash ဖြင့် ညွှန်းဆိုထားသည့် အကြောင်းအရာကို ကြည့်ရှုပါက အောက်ပါအတိုင်း ရရှိမည်ဖြစ်သည် -

git is wonderful

References (ညွှန်းဆိုချက်များ)

ယခုအခါ snapshot အားလုံးကို ၎င်းတို့၏ SHA-1 hash များနှင့် ခွဲခြားသတ်မှတ်နိုင်ပြီ ဖြစ်သည်။ သို့သော် လူများသည် ၁၆ ခြောက်လီစနစ် (hexadecimal) စာလုံး ၄၀ ပါသော စာကြောင်းများကို မှတ်မိရန် မလွယ်ကူသောကြောင့် ၎င်းမှာ အဆင်မပြေပါ။

ဤပြဿနာအတွက် Git ၏ ဖြေရှင်းချက်မှာ “references” ဟုခေါ်သော SHA-1 hash များအတွက် လူများ ဖတ်ရှုနိုင်သည့် အမည်များ ဖြစ်သည်။ References များသည် commit များကို ညွှန်ပြသော pointer များ ဖြစ်ကြသည်။ ပြောင်းလဲ၍မရသော (immutable) object များနှင့် မတူဘဲ references များသည် ပြောင်းလဲနိုင်သည် (mutable - commit အသစ်ကို ညွှန်ပြရန် အပ်ဒိတ်လုပ်နိုင်သည်)။ ဥပမာအားဖြင့် master reference သည် များသောအားဖြင့် ပင်မ ဖွံ့ဖြိုးတိုးတက်ရေး branch ၏ နောက်ဆုံး commit ကို ညွှန်ပြလေ့ရှိသည်။

references = map<string, string>

def update_reference(name, id):
    references[name] = id

def read_reference(name):
    return references[name]

def load_reference(name_or_id):
    if name_or_id in references:
        return load(references[name_or_id])
    else:
        return load(name_or_id)

ဤအရာဖြင့် Git သည် ရှည်လျားသော hexadecimal စာကြောင်းအစား မှတ်တမ်းရှိ သီးခြား snapshot တစ်ခုကို ညွှန်းဆိုရန် “master” ကဲ့သို့သော လူများ ဖတ်ရှုနိုင်သည့် အမည်များကို အသုံးပြုနိုင်သည်။

အသေးစိတ်တစ်ခုမှာ snapshot အသစ်တစ်ခု ရယူသည့်အခါ မည်သည့်အရာနှင့် နှိုင်းယှဉ်ထားသည်ကို သိရှိစေရန် (commit ၏ parents field ကို မည်သို့ သတ်မှတ်ရမည်ဆိုသည်) မှတ်တမ်းတွင် “ကျွန်ုပ်တို့ လက်ရှိ မည်သည့်နေရာသို့ ရောက်ရှိနေသည်” ဆိုသည့် အယူအဆကို လိုချင်ကြသည်။ Git တွင် ထို “ကျွန်ုပ်တို့ လက်ရှိ ရောက်ရှိနေသည့်နေရာ” သည် “HEAD” ဟုခေါ်သော အထူး reference တစ်ခု ဖြစ်သည်။

Repositories

နောက်ဆုံးတွင် Git repository ၏ အဓိပ္ပာယ်ကို (ကြမ်းဖျင်းအားဖြင့်) အဓိပ္ပာယ်ဖွင့်ဆိုနိုင်သည် - ၎င်းသည် data objects နှင့် references တို့ ဖြစ်သည်။

Disk ပေါ်တွင် Git သိမ်းဆည်းထားသမျှ အရာအားလုံးသည် objects နှင့် references များဖြစ်သည် - ၎င်းသည် Git ၏ data model တွင် ရှိသမျှ အရာအားလုံးပင် ဖြစ်သည်။ git command အားလုံးသည် objects များကို ထည့်သွင်းခြင်းနှင့် references များကို ထည့်သွင်းခြင်း/အပ်ဒိတ်လုပ်ခြင်းဖြင့် commit DAG ကို ပြုပြင်ပြောင်းလဲမှု အချို့ ပြုလုပ်ခြင်းသို့ ချိတ်ဆက်နေသည်။

Command တစ်ခုခုကို ရိုက်ထည့်သည့်အခါတိုင်း၊ ၎င်း command သည် အခြေခံ graph data structure ကို မည်သည့် ပြုပြင်ပြောင်းလဲမှု ပြုလုပ်နေသည်ဆိုသည်ကို စဉ်းစားပါ။ အပြန်အလှန်အားဖြင့် commit DAG ကို “commit မလုပ်ရသေးသော ပြောင်းလဲမှုများကို ပယ်ဖျက်ပြီး ‘master’ ref ကို commit 5d83f9e သို့ ညွှန်ပြစေခြင်း” ကဲ့သို့သော သီးခြား ပြောင်းလဲမှုမျိုး ပြုလုပ်ရန် ကြိုးစားနေပါက ၎င်းကို ပြုလုပ်ရန် command တစ်ခုခု ရှိနိုင်ပါသည် (ဥပမာ - ဤဖြစ်ရပ်တွင် git checkout master; git reset --hard 5d83f9e)။

Staging area

ဤသည်မှာ data model နှင့် သီးခြားစီ ဖြစ်သော်လည်း commit များကို ဖန်တီးရန် interface ၏ အစိတ်အပိုင်းတစ်ခု ဖြစ်သော အခြား အယူအဆတစ်ခု ဖြစ်သည်။

အထက်တွင် ဖော်ပြခဲ့သည့်အတိုင်း snapshot ရယူခြင်းကို အကောင်အထည်ဖော်ရန် စဉ်းစားနိုင်သည့် နည်းလမ်းတစ်ခုမှာ working directory ၏ လက်ရှိ အခြေအနေ ပေါ် အခြေခံ၍ snapshot အသစ်တစ်ခု ဖန်တီးပေးသည့် “create snapshot” command တစ်ခု ရှိခြင်း ဖြစ်သည်။ အချို့သော version control tools များသည် ဤကဲ့သို့ အလုပ်လုပ်သော်လည်း Git ကမူ မဟုတ်ပါ။ ကျွန်ုပ်တို့သည် သပ်ရပ်သန့်ရှင်းသော snapshot များကို လိုချင်ကြပြီး လက်ရှိ အခြေအနေမှ snapshot ပြုလုပ်ခြင်းသည် အမြဲတမ်း သင့်တော်မည် မဟုတ်ပါ။ ဥပမာအားဖြင့် သင်သည် သီးခြား feature နှစ်ခုကို အကောင်အထည်ဖော်ထားပြီး သီးခြား commit နှစ်ခု ဖန်တီးလိုသည့် အခြေအနေကို မြင်ယောင်ကြည့်ပါ၊ ပထမတစ်ခုက ပထမ feature ကို မိတ်ဆက်ပေးပြီး နောက်တစ်ခုက ဒုတိယ feature ကို မိတ်ဆက်ပေးမည် ဖြစ်သည်။ သို့မဟုတ် အမှားပြင်ဆင်မှု (bugfix) တစ်ခုနှင့်အတူ သင့်ကုဒ်တစ်လျှောက် ထည့်သွင်းထားသော debugging print စာကြောင်းများ ရှိနေသည့် အခြေအနေကို မြင်ယောင်ကြည့်ပါ၊ print စာကြောင်းများအားလုံးကို ပယ်ဖျက်ပြီး bugfix ကိုသာ commit လုပ်လိုမည် ဖြစ်သည်။

Git သည် “staging area” ဟုခေါ်သော နည်းလမ်းမှတစ်ဆင့် နောက် snapshot တွင် မည်သည့် ပြုပြင်ပြောင်းလဲမှုများ ပါဝင်သင့်သည်ကို သတ်မှတ်ခွင့်ပြုခြင်းဖြင့် ထိုကဲ့သို့သော အခြေအနေများကို ဖြည့်ဆည်းပေးသည်။

Git command-line interface

အချက်အလက်များ ထပ်နေခြင်းကို ရှောင်ရှားရန်အတွက် ဤသင်ခန်းစာ မှတ်စုများတွင် အောက်ပါ command များကို အသေးစိတ် ရှင်းပြမည် မဟုတ်ပါ။ ပိုမိုသိရှိလိုပါက လွန်စွာ အကြံပြုထားသော Pro Git စာအုပ်ကို ဖတ်ရှုပါ သို့မဟုတ် သင်ခန်းစာ ဗီဒီယိုကို ကြည့်ရှုပါ။

အခြေခံများ

Branch ခွဲခြင်းနှင့် ပေါင်းစည်းခြင်း (Branching and merging)

Remotes

ပြန်လည်ရုပ်သိမ်းခြင်း (Undo)

အဆင့်မြင့် Git

အထွေထွေ

လေ့လာရန် အရင်းအမြစ်များ

လေ့ကျင့်ခန်းများ

  1. သင့်တွင် ယခင်က Git အတွေ့အကြုံ မရှိပါက Pro Git ၏ ပထမ အခန်းအနည်းငယ်ကို ဖတ်ကြည့်ပါ သို့မဟုတ် Learn Git Branching ကဲ့သို့သော သင်ခန်းစာကို လေ့လာပါ။ လေ့ကျင့် လုပ်ဆောင်နေချိန်တွင် Git command များကို data model နှင့် ဆက်စပ်ကြည့်ပါ။
  2. သင်တန်းဝဘ်ဆိုက်အတွက် repository ကို clone လုပ်ပါ။
    1. Version history ကို graph အဖြစ် အမြင်ပုံဖော်ကြည့်ခြင်းဖြင့် လေ့လာစုံစမ်းပါ။
    2. README.md ကို နောက်ဆုံး ပြင်ဆင်ခဲ့သူမှာ မည်သူနည်း။ (လမ်းညွှန် - argument ပါဝင်သော git log ကို အသုံးပြုပါ)။
    3. _config.yml ၏ collections: လိုင်းသို့ နောက်ဆုံး ပြင်ဆင်မှုနှင့် သက်ဆိုင်သည့် commit မက်ဆေ့ဂျ်မှာ မည်သည့်အရာ ဖြစ်သနည်း။ (လမ်းညွှန် - git blame နှင့် git show ကို အသုံးပြုပါ)။
  3. Git ကို လေ့လာရာတွင် တွေ့ရလေ့ရှိသော အမှားတစ်ခုမှာ Git ဖြင့် မထိန်းချုပ်သင့်သော ဖိုင်ကြီးများကို commit လုပ်မိခြင်း သို့မဟုတ် လျှို့ဝှက်ချက် အချက်အလက်များကို ထည့်သွင်းမိခြင်း ဖြစ်သည်။ ဖိုင်တစ်ခုကို repository သို့ ထည့်သွင်းကြည့်ပါ၊ commit အချို့ ပြုလုပ်ပြီး ထိုဖိုင်ကို history မှ (နောက်ဆုံး commit တစ်ခုတည်းမှ မဟုတ်ဘဲ) ဖျက်ပစ်ပါ။ သင်သည် ဤနေရာ ကို ကြည့်ရှုလိုပေမည်။
  4. GitHub မှ repository တစ်ခုကို clone လုပ်ပြီး ၎င်း၏ လက်ရှိ ဖိုင်တစ်ခုကို ပြင်ဆင်ပါ။ git stash လုပ်သည့်အခါ မည်သို့ ဖြစ်ပျက်သနည်း။ git log --all --oneline ကို runသည့်အခါ မည်သည့်အရာကို တွေ့ရသနည်း။ git stash ဖြင့် သင်ပြုလုပ်ခဲ့သည်ကို ပြန်ဖြုတ်ရန် git stash pop ကို runပါ။ မည်သည့် အခြေအနေမျိုးတွင် ဤသည် အသုံးဝင်နိုင်သနည်း။
  5. Command line tools အများအပြားကဲ့သို့ပင် Git သည် ~/.gitconfig ဟုခေါ်သော configuration file (သို့မဟုတ် dotfile) ကို ပံ့ပိုးပေးထားသည်။ ~/.gitconfig တွင် alias တစ်ခု ဖန်တီးပါ၊ သို့မှသာ သင်သည် git graph ကို runသည့်အခါ git log --all --graph --decorate --oneline ၏ output ကို ရရှိမည်ဖြစ်သည်။ ဤအရာကို ~/.gitconfig ဖိုင်ကို တိုက်ရိုက် ပြင်ဆင်ခြင်း ဖြင့် ပြုလုပ်နိုင်သည် သို့မဟုတ် alias ထည့်သွင်းရန် git config command ကို အသုံးပြုနိုင်သည်။ Git alias များအကြောင်း အချက်အလက်များကို ဤနေရာ တွင် တွေ့နိုင်ပါသည်။
  6. git config --global core.excludesfile ~/.gitignore_global ကို runပြီးနောက် ~/.gitignore_global တွင် အထွေထွေ (global) ignore pattern များကို သတ်မှတ်နိုင်သည်။ ဤသည်မှာ Git အသုံးပြုမည့် global ignore file ၏ တည်နေရာကို သတ်မှတ်ပေးခြင်း ဖြစ်သော်လည်း ထိုလမ်းကြောင်းတွင် ဖိုင်ကို ကိုယ်တိုင် ဖန်တီးရန် လိုအပ်နေသေးသည်။ OS သို့မဟုတ် editor သီးသန့် ယာယီဖိုင်များဖြစ်သော .DS_Store ကဲ့သို့သော အရာများကို လျစ်လျူရှုရန် သင့် global gitignore file ကို သတ်မှတ်ပါ။
  7. သင်တန်းဝဘ်ဆိုက်အတွက် repository ကို Fork လုပ်ပါ၊ စာလုံးပေါင်းမှားခြင်း သို့မဟုတ် အခြား တိုးတက်ကောင်းမွန်အောင် ပြုလုပ်နိုင်သည့်အရာတစ်ခုကို ရှာဖွေပြီး GitHub တွင် pull request တစ်ခု တင်သွင်းပါ (ဤနေရာ ကို ကြည့်ရှုလိုပေမည်)။ ကျေးဇူးပြု၍ အသုံးဝင်သော PR များကိုသာ တင်သွင်းပါ (ကျွန်ုပ်တို့ထံ spam မလုပ်ပါနှင့်!)။ ပြုလုပ်ရန် တိုးတက်ကောင်းမွန်မှု မရှာတွေ့ပါက ဤလေ့ကျင့်ခန်းကို ကျော်သွားနိုင်ပါသည်။
  8. ပူးပေါင်း လုပ်ဆောင်သည့် အခြေအနေတစ်ခုကို အတုယူ ဖန်တီးခြင်းဖြင့် merge conflict များကို ဖြေရှင်းခြင်းကို လေ့ကျင့်ပါ -
    1. git init ဖြင့် repository အသစ်တစ်ခု ဖန်တီးပြီး စာကြောင်းအနည်းငယ် ပါဝင်သော recipe.txt ဟုခေါ်သော ဖိုင်တစ်ခု ဖန်တီးပါ (ဥပမာ - ရိုးရှင်းသော ဟင်းချက်နည်းတစ်ခု)။
    2. ၎င်းကို commit လုပ်ပါ၊ ထို့နောက် branch နှစ်ခု ဖန်တီးပါ - git branch salty နှင့် git branch sweet။
    3. salty branch တွင် စာကြောင်းတစ်လိုင်းကို ပြင်ဆင်ပါ (ဥပမာ - “1 cup sugar” မှ “1 cup salt” သို့ ပြောင်းပါ) ပြီးလျှင် commit လုပ်ပါ။
    4. sweet branch တွင် ထိုစာကြောင်းကိုပင် မတူညီဘဲ ပြင်ဆင်ပါ (ဥပမာ - “1 cup sugar” မှ “2 cups sugar” သို့ ပြောင်းပါ) ပြီးလျှင် commit လုပ်ပါ။
    5. ယခု master သို့ ပြောင်းပြီး git merge salty၊ ထို့နောက် git merge sweet ကို စမ်းကြည့်ပါ။ မည်သို့ ဖြစ်ပျက်သနည်း။ recipe.txt ၏ ပါဝင်သည့်အရာများကို ကြည့်ပါ - <<<<<<<၊ ======= နှင့် >>>>>>> အမှတ်အသားများသည် မည်သည့်အရာကို ဆိုလိုသနည်း။
    6. သင်လိုချင်သော အကြောင်းအရာကို သိမ်းဆည်းရန် ဖိုင်ကို ပြင်ဆင်ခြင်း၊ conflict အမှတ်အသားများကို ဖျက်ထုတ်ခြင်းနှင့် git add နှင့် git commit (သို့မဟုတ် git merge --continue) တို့ဖြင့် ပေါင်းစည်းခြင်းကို ပြီးမြောက်စေခြင်းဖြင့် conflict ကို ဖြေရှင်းပါ။ သို့မဟုတ်ဘဲ graphical သို့မဟုတ် terminal အခြေပြု merge tool တစ်ခုဖြင့် conflict ကို ဖြေရှင်းရန် git mergetool ကို အသုံးပြုကြည့်ပါ။
    7. သင် ယခုလေးတင် ဖန်တီးခဲ့သော merge history ကို အမြင်ပုံဖော်ရန် git log --graph --oneline ကို အသုံးပြုပါ။

Edit this page.

Licensed under CC BY-NC-SA.