Version Control (Git)

Version control systems (VCSs) ဆိုသည်မှာ Source Code များ (သို့မဟုတ် အခြား ဖိုင်နှင့် Folder စုစည်းမှုများ) ၏ အပြောင်းအလဲများကို ခြေရာခံရန် အသုံးပြုသည့် Tool များ ဖြစ်ကြသည်။ အမည်တွင် ဖော်ပြထားသည့်အတိုင်း ဤ Tool များသည် အပြောင်းအလဲများ၏ သမိုင်းကြောင်းကို ထိန်းသိမ်းပေးသည့်အပြင် အခြားသူများနှင့် ပူးပေါင်းဆောင်ရွက်မှုကိုလည်း လွယ်ကူစေပါသည်။ VCS များသည် Folder တစ်ခုနှင့် ယင်း၏ ပါဝင်မှုများကို ပုံရိပ်လွှာ (snapshot) အစဉ်လိုက်များဖြင့် ခြေရာခံပေးပြီး၊ Snapshot တစ်ခုစီသည် Top-level Directory အတွင်းရှိ ဖိုင်/Folder များ၏ အခြေအနေတစ်ခုလုံးကို ငုံ့ကြည့်နိုင်အောင် စုစည်းထားပေးပါသည်။ ထို့အပြင် VCS များသည် Snapshot တစ်ခုစီကို မည်သူဖန်တီးခဲ့သည်၊ အမှတ်အသား စာတိုများ (messages) အစရှိသည့် Metadata များကိုပါ ထိန်းသိမ်းပေးပါသည်။

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

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

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

xkcd 1597

Git ၏ Interface သည် leaky abstraction ဖြစ်သောကြောင့် Git ကို Top-down နည်းလမ်းဖြင့် (ယင်း၏ Interface / Command-line Interface မှ စတင်၍) လေ့လာခြင်းသည် ရှုပ်ထွေးမှုများစွာ ဖြစ်ပေါ်စေနိုင်ပါသည်။ Command အနည်းငယ်ကို အလွတ်ကျက်မှတ်ထားပြီး မန္တန်အဖြစ် မှတ်ယူကာ၊ ပြဿနာ တစ်ခုခု တက်လာပါက အထက်ပါ Comic ပါ အယူအဆအတိုင်း ပြုလုပ်လေ့ ရှိကြပါသည်။

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

Git’s data model

Version control အတွက် အသုံးပြုနိုင်သော နည်းလမ်းများစွာ ရှိပါသည်။ Git တွင် Version control ၏ အင်္ဂါရပ်ကောင်းများဖြစ်သော သမိုင်းကြောင်း ထိန်းသိမ်းခြင်း၊ Branch များကို ထောက်ပံ့ခြင်း နှင့် ပူးပေါင်းဆောင်ရွက်မှုကို လွယ်ကူစေခြင်း အစရှိသည်တို့ကို အပြည့်အဝ ပေးစွမ်းနိုင်သည့် သေချာစွာ စနစ်တကျ ရေးဆွဲထားသော Model တစ်ခု ရှိပါသည်။

Snapshots

Git သည် Top-level Directory တွင်းရှိ ဖိုင်များနှင့် Folder များ စုစည်းမှု၏ သမိုင်းကြောင်းကို Snapshot များ အစဉ်လိုက်အဖြစ် ပုံဖော်ထားပါသည်။ Git ဝေါဟာရတွင် ဖိုင်ကို “blob” ဟု ခေါ်ဆိုပြီး ယင်းသည် Byte အစုအဝေးမျှသာ ဖြစ်သည်။ Directory ကို “tree” ဟု ခေါ်ဆိုပြီး ယင်းသည် အမည်များကို blobs သို့မဟုတ် trees သို့ ချိတ်ဆက်ပေးပါသည် (ထို့ကြောင့် Directory များတွင် အခြား Directory များ ပါဝင်နိုင်သည်)။ Snapshot ဆိုသည်မှာ ခြေရာခံနေသော Top-level Tree ဖြစ်ပါသည်။ ဥပမာအားဖြင့် အောက်ပါအတိုင်း Tree တစ်ခု ရှိနိုင်ပါသည် -

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

Top-level Tree တွင် အစိတ်အပိုင်း နှစ်ခု ပါဝင်ပါသည်၊ “foo” ဟုခေါ်သော Tree တစ်ခု (၎င်းကိုယ်တိုင်တွင် “bar.txt” ဟုခေါ်သော blob တစ်ခု ပါဝင်သည်) နှင့် “baz.txt” ဟုခေါ်သော blob တစ်ခုတို့ ဖြစ်ကြသည်။

Modeling history: relating snapshots

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

Git တွင် သမိုင်းကြောင်းဆိုသည်မှာ Snapshot များ၏ Directed Acyclic Graph (DAG) ဖြစ်ပါသည်။ ဤသည်မှာ သင်္ချာစကားလုံးဆန်း ဖြစ်ကောင်းဖြစ်နိုင်သော်လည်း စိတ်မပူပါနှင့်။ ဤသည်၏ အဓိပ္ပာယ်မှာ Git ရှိ Snapshot တစ်ခုစီသည် ယင်း၏ အလျင် ရှိခဲ့သော မိဘများ “parents” ၏ အစုအဝေးကို ညွှန်းဆိုနေခြင်း ဖြစ်ပါသည်။ မိဘ တစ်ခုတည်း (linear history တွင် ဖြစ်သကဲ့သို့) မဟုတ်ဘဲ မိဘ အစုအဝေး ဖြစ်နေရခြင်းမှာ Snapshot တစ်ခုသည် မိဘများစွာမှ ဆင်းသက်လာနိုင်သောကြောင့် ဖြစ်သည် (ဥပမာ ပြိုင်တူ ဖွံ့ဖြိုးတိုးတက်နေသော Branch နှစ်ခုကို ပေါင်းစပ် merge လုပ်လိုက်သည့်အခါမျိုးတွင် ဖြစ်သည်)။

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

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

အထက်ပါ ASCII Art တွင် o များသည် သီးခြား Commit (snapshot) များကို ကိုယ်စားပြုပါသည်။ မြားများသည် Commit တစ်ခုစီ၏ Parent ကို ညွှန်ပြနေခြင်း ဖြစ်ပါသည် (“နောက်မှ လာသည်” မဟုတ်ဘဲ “ရှေ့မှ လာသည်” ဆက်ဆံရေး ဖြစ်သည်)။ တတိယ Commit ပြီးနောက် သမိုင်းကြောင်းသည် သီးခြား Branch နှစ်ခုအဖြစ် ခွဲထွက်သွားသည်။ ဤသည်မှာ ဥပမာအားဖြင့် သီးခြား Feature နှစ်ခုကို တစ်ပြိုင်နက်တည်း သီးခြားစီ ဖွံ့ဖြိုးတိုးတက်အောင် ပြုလုပ်နေခြင်းနှင့် တူညီပါသည်။ နောင်တွင် ဤ Branch နှစ်ခုကို Merge ပြုလုပ်၍ Feature နှစ်ခုစလုံး ပါဝင်သော Snapshot အသစ်တစ်ခုကို ဖန်တီးနိုင်ပြီး၊ အောက်ပါအတိုင်း သမိုင်းကြောင်း အသစ်တစ်ခု ထွက်ပေါ်လာမည် ဖြစ်ကာ Merge commit အသစ်ကို စာလုံးအထူဖြင့် ဖော်ပြထားပါသည် -


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

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

Data model, as pseudocode

Git ၏ Data model ကို Pseudocode ဖြင့် ရေးသားထားသည်ကို ကြည့်ပါက ပိုမို ရှင်းလင်းသွားပါမည် -

// file ဆိုသည်မှာ Byte အစုအဝေး ဖြစ်သည်
type blob = array<byte>

// directory တွင် အမည်တပ်ထားသော ဖိုင်များနှင့် directory များ ပါဝင်သည်
type tree = map<string, tree | blob>

// commit တွင် parents, metadata နှင့် top-level tree တို့ ပါဝင်သည်
type commit = struct {
    parents: array<commit>
    author: string
    message: string
    snapshot: tree
}

ဤသည်မှာ သမိုင်းကြောင်း၏ သပ်ရပ်ရှင်းလင်းသော Model ဖြစ်ပါသည်။

Objects and content-addressing

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

type object = blob | tree | commit

Git data store တွင် object အားလုံးကို ယင်းတို့၏ SHA-1 hash ဖြင့် Content-addressing ပြုလုပ်ထားပါသည် -

objects = map<string, object>

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

def load(id):
    return objects[id]

Blobs, trees နှင့် commits များကို ဤနည်းဖြင့် ပေါင်းစည်းထားပါသည် - ယင်းတို့ အားလုံးသည် object များ ဖြစ်ကြသည်။ ယင်းတို့သည် အခြား object များကို ညွှန်းဆိုသည့်အခါ၊ Disc ပေါ်တွင် Object တစ်ခုလုံးကို ထည့်သွင်း ထားခြင်း မဟုတ်ဘဲ Hash ဖြင့် ညွှန်းဆိုထားသော Reference ကိုသာ သိမ်းဆည်းထားပါသည်။

ဥပမာအားဖြင့် အထက်ပါ Directory စနစ်၏ Tree ကို (git cat-file -p 698281bc680d1995c5f4caaf3359721a5a58d48d ဖြင့် ကြည့်ရှုထားသော) အောက်ပါအတိုင်း တွေ့ရပါမည် -

100644 blob 4448adbf7ecd394f42ae135bbeed9676e894af85    baz.txt
040000 tree c68d233a33c5c06e0340e4c224f0afca87c8ce87    foo

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

git is wonderful

References

ယခုအခါ Snapshot အားလုံးကို SHA-1 Hashes များဖြင့် ခွဲခြားသတ်မှတ်နိုင်ပြီ ဖြစ်သည်။ သို့သော် လူများသည် 16 စီးပါ 40-digit Hexadecimal စာလုံးများကို မှတ်မိရန် မလွယ်ကူသဖြင့် အဆင်မပြေပါ။

ဤပြဿနာအတွက် Git ၏ ဖြေရှင်းချက်မှာ SHA-1 Hashes များကို လူနားလည်လွယ်သော အမည်များ ပေးခြင်းဖြစ်ပြီး ယင်းတို့ကို “References” ဟု ခေါ်ဆိုပါသည်။ References များသည် Commit များကို ညွှန်ပြသော Pointers များ ဖြစ်ကြသည်။ မပြောင်းလဲနိုင်သော Objects များနှင့် မတူဘဲ References များသည် ပြောင်းလဲနိုင်ပါသည် (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 String အစား “master” ကဲ့သို့သော လူနားလည်လွယ်သော အမည်များကို သမိုင်းကြောင်းရှိ သီးခြား Snapshot များကို ညွှန်းဆိုရန် အသုံးပြုနိုင်ပါသည်။

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

Repositories

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

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

Command တစ်ခုခုကို ရိုက်နှိပ်လိုက်တိုင်း၊ ထို Command သည် အောက်ခံ Graph Data Structure ကို မည်သို့ ပြောင်းလဲနေသည်ဆိုသည်ကို စဉ်းစားပါ။ အလားတူပင် Commit DAG သို့ သီးခြား ပြောင်းလဲမှုတစ်ခုခု ပြုလုပ်လိုပါက (ဥပမာ “မသိမ်းရသေးသော အပြောင်းအလဲများကို စွန့်ပစ်ပြီး ‘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 tool များသည် ဤသို့ အလုပ်လုပ်ကြသော်လည်း Git မဟုတ်ပါ။ ကျွန်ုပ်တို့သည် သပ်ရပ်သန့်ရှင်းသော Snapshot များကို အလိုရှိကြပြီး၊ လက်ရှိ အခြေအနေ တစ်ခုလုံးမှ Snapshot ရယူခြင်းသည် အမြဲတမ်း မသင့်တော်နိုင်ပါ။ ဥပမာအားဖြင့် သီးခြား Feature နှစ်ခုကို ရေးသားထားပြီး သီးခြား Commit နှစ်ခု ဖန်တီးလိုသည် ဆိုပါစို့၊ ပထမ Commit တွင် ပထမ Feature ပါဝင်ပြီး ဒုတိယ Commit တွင် ဒုတိယ Feature ပါဝင်စေလိုသည်။ သို့မဟုတ် Code တွင် ပုံနှိပ်ထုတ်ဝေထားသော Debugging print စာကြောင်းများ ပါဝင်နေပြီး Bugfix နှင့်အတူ ရောနှောနေသည် ဆိုပါစို့၊ Bugfix ကိုသာ Commit လုပ်ပြီး Print စာကြောင်းများကို စွန့်ပစ်လိုပါမည်။

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

Git command-line interface

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

Basics

Branching and merging

Remotes

Undo

Advanced Git

Miscellaneous

Resources

Exercises

  1. Git နှင့် ပတ်သက်၍ အတွေ့အကြုံ မရှိသေးပါက Pro Git ၏ ပထမ အခန်းအနည်းငယ်ကို ဖတ်ပါ သို့မဟုတ် Learn Git Branching သင်ခန်းစာကို ပြုလုပ်ပါ။ ပြုလုပ်နေစဉ်အတွင်း Git command များကို Data model နှင့် ယှဉ်တွဲ စဉ်းစားပါ။
  2. ဤအတန်း၏ ဝဘ်ဆိုက် repository ကို Clone လုပ်ပါ။
    1. သမိုင်းကြောင်းကို Graph အဖြစ် ကြည့်ရှု၍ လေ့လာပါ။
    2. README.md ကို နောက်ဆုံး ပြင်ဆင်ခဲ့သူမှာ မည်သူနည်း။ (အချက်အလက်- git log ကို argument ဖြင့် သုံးပါ)။
    3. _config.yml ၏ collections: စာကြောင်းကို နောက်ဆုံး ပြင်ဆင်ခဲ့သည့် commit ၏ message မှာ ဘာနည်း။ (အချက်အလက်- git blame နှင့် git show ကို သုံးပါ)။
  3. Git လေ့လာရာတွင် အတွေ့ရများသော အမှားတစ်ခုမှာ Git ဖြင့် မစီမံသင့်သော ဖိုင်ကြီးများကို Commit လုပ်မိခြင်း သို့မဟုတ် အရေးကြီးသော အချက်အလက်များကို ထည့်သွင်းမိခြင်း ဖြစ်သည်။ Repository သို့ ဖိုင်တစ်ခု ထည့်ပါ၊ Commit လုပ်ပါ၊ ထို့နောက် သမိုင်းကြောင်းထဲမှ ထိုဖိုင်ကို ပယ်ဖျက်ပါ (ဤနေရာတွင် ကြည့်ရှုနိုင်သည်)။
  4. GitHub မှ Repository တစ်ခုကို Clone လုပ်ပါ၊ ရှိပြီးသား ဖိုင်တစ်ခုကို ပြင်ပါ။ git stash runလိုက်သည့်အခါ မည်သို့ ဖြစ်သွားသနည်း။ git log --all --oneline runသည့်အခါ မည်သည်ကို တွေ့ရသနည်း။ git stash pop run၍ ပြုလုပ်ခဲ့သည်ကို ပြန်ဖျက်ပါ။ မည်သည့် အခြေအနေတွင် ဤသည်မှာ အသုံးဝင်သနည်း။
  5. Command line tool အများစုကဲ့သို့ပင် Git တွင် ~/.gitconfig ဟုခေါ်သော Configuration file (dotfile) ပါရှိသည်။ ~/.gitconfig တွင် Alias တစ်ခု ဖန်တီး၍ git graph runလိုက်ပါက git log --all --graph --decorate --oneline ၏ output ရရှိအောင် ပြုလုပ်ပါ။ ~/.gitconfig ဖိုင်ကို တိုက်ရိုက် ပြင်ဆင်ခြင်း ဖြင့်လည်းကောင်း၊ git config command ဖြင့်လည်းကောင်း ပြုလုပ်နိုင်ပါသည်။ Git alias အကြောင်းကို ဒီမှာ ကြည့်နိုင်ပါသည်။
  6. git config --global core.excludesfile ~/.gitignore_global ကို runပြီးနောက် ~/.gitignore_global တွင် Global ignore pattern များကို သတ်မှတ်နိုင်ပါသည်။ ဤသည်မှာ Git အသုံးပြုမည့် Global ignore file နေရာကို သတ်မှတ်ပေးခြင်း ဖြစ်သော်လည်း ထိုလမ်းကြောင်းတွင် ဖိုင်ကို ကိုယ်တိုင် ဖန်တီးရန် လိုအပ်ဆဲ ဖြစ်သည်။ သင်၏ Global gitignore ဖိုင်တွင် OS သို့မဟုတ် Editor သီးသန့် ယာယီဖိုင်များ (ဥပမာ .DS_Store) ကို Ignore လုပ်ရန် သတ်မှတ်ပါ။
  7. ဤအတန်း၏ ဝဘ်ဆိုက် repository ကို Fork လုပ်ပါ၊ စာလုံးပေါင်း မှားယွင်းမှု သို့မဟုတ် တိုးတက်ကောင်းမွန်အောင် ပြုလုပ်နိုင်မည့် အရာကို ရှာပြီး GitHub တွင် Pull Request တင်ပါ (ဤနေရာတွင် ကြည့်နိုင်ပါသည်)။ အသုံးဝင်သော PR များကိုသာ တင်ပေးပါ (ကျေးဇူးပြု၍ Spam မလုပ်ပါနှင့်!)။ တိုးတက်အောင် ပြုလုပ်စရာ မတွေ့ပါက ဤလေ့ကျင့်ခန်းကို ကျော်နိုင်ပါသည်။

Edit this page.

Licensed under CC BY-NC-SA.