Thuta Learning
Git & GitHub: Collaboration and Professional Workflows
BasicDevOps & Toolsintermediate

Fetch vs Pull vs Clone vs Fork

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Fetch vs Pull vs Clone vs Fork concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram ကို ဖတ်ပြီး Git/GitHub workflow ထဲမှာ state (သို့) data ဘယ်လိုစီးဆင်းသလဲ ခြေရာခံနိုင်ရန်
  • ကိုယ့် project/team အတွက် ဘယ်လို အသုံးချသင့်သလဲ ဆုံးဖြတ်နိုင်ရန်

နားလည်ထားရမယ့် အချက်

Four words အမြဲ ရောထွေးလေ့ရှိတဲ့ clone, fork, fetch, pull ဆိုတာလေးခု ရှိပါတယ်။ တစ်ခုချင်းစီက ကွဲပြားတဲ့ အလုပ်လုပ်ပြီး ရောထွေးလိုက်ရင် တကယ့်ရှုပ်ထွေးမှုကို ဖြစ်စေပါတယ်။

Clone ဆိုတာ remote repository တစ်ခုလုံး — history, branch အားလုံး — ကို သင့် local ကွန်ပျူတာထဲကို တစ်ကြိမ်တည်း ကူးယူတာဖြစ်ပြီး Git tutorial မှာ သင်အသုံးပြုခဲ့ပြီးသားပါ။

Fork ကတော့ အမျိုးအစားလုံးဝ ကွဲပါတယ် — GitHub server ပေါ်မှာသာ လုံးဝဖြစ်ပေါ်ပြီး၊ တခြားသူတစ်ဦး၏ repository ကို သင့်ကိုယ်ပိုင် GitHub account ထဲကို ကူးယူတာဖြစ်ပြီး local ကွန်ပျူတာ လုံးဝမပါဝင်ပါဘူး။ Push access မရှိတဲ့ project တစ်ခုကို contribute လုပ်ဖို့ ပထမဆုံးအဆင့်အဖြစ် fork လုပ်ဖို့ များသောအားဖြင့် လိုအပ်ပါတယ်။

Operationအသေးစိတ်
Cloneသင့် local ကွန်ပျူတာထဲကို တစ်ကြိမ်တည်း ကူးယူသည်။ ဆက်တိုက် sync မဟုတ်ပါ — ၎င်းသည် အစပထမ မိတ္တူသာ ဖြစ်သည်။
Forkသင့်ကိုယ်ပိုင် GitHub account ထဲကို (server-side) ကူးယူသည်။ Merge လုံးဝမပါ — remote repository အသစ်တစ်ခု ဖြစ်လာသည်။
Fetchremote commit များကို local origin/main tracking ref ထဲသို့ ကူးယူသည်။ သင့်လက်ရှိ branch ထဲသို့ merge မလုပ်ပါ။
Pullremote commit များကို ကူးယူပြီး သင့်လက်ရှိ branch ထဲသို့ တစ်ဆင့်တည်းနှင့် ချက်ချင်း merge လုပ်သည်။

Fetch ကတော့ remote ကနေ commit အသစ်တွေကို download လုပ်ပြီး origin/main လို remote-tracking reference တစ်ခုအောက်မှာ သိမ်းထားပါတယ် — သင့် လက်ရှိ branch ဘာမှမရွေ့ပါ၊ working file တွေလည်း လုံးဝမပြောင်းပါဘူး။

Pull ကတော့ download တူတူလုပ်ပြီး အဲဒီ commit အသစ်တွေကို သင့်လက်ရှိ branch ထဲကို တစ်ဆင့်တည်းနှင့် merge ချက်ချင်း လုပ်ပါတယ်။ ဒါကြောင့်ပဲ pull က တစ်ခါတလေ အံ့သြစရာဖြစ်တတ်ပါတယ် — automatic merge commit ဒါမှမဟုတ် conflict တောင် ရုတ်တရက် ပေါ်လာနိုင်ပါတယ်။

ပိုလုံခြုံသော အလေ့အထ

Fetch အရင်လုပ်ပြီး git log origin/main လိုမျိုးနှင့် ဘာပြောင်းလဲသွားလဲ ကြည့်ပြီးမှ merge လုပ်တာက contributor တစ်ဦးထက်ပိုတဲ့ repository တစ်ခုအတွက် ပိုလုံခြုံတဲ့ အလေ့အထပါ။

Clone
Remote repository တစ်ခုလုံး — history, branch အားလုံးပါ — ကို သင့် local ကွန်ပျူတာထဲကို တစ်ကြိမ်တည်း ကူးယူခြင်း။
Fork
တခြားသူတစ်ဦး၏ repository ကို GitHub server ပေါ်မှာသာ သင့်ကိုယ်ပိုင် account ထဲကို ကူးယူခြင်း၊ local ကွန်ပျူတာ လုံးဝမပါဝင်ပါ။
Fetch
Remote ကနေ commit အသစ်များကို local tracking reference (origin/main လို) ထဲသို့ download လုပ်ခြင်း၊ လက်ရှိ branch ကို မထိပါ။
Pull
Remote ကနေ commit အသစ်များကို fetch လုပ်ပြီး သင့်လက်ရှိ branch ထဲသို့ တစ်ဆင့်တည်းနှင့် ချက်ချင်း merge လုပ်ခြင်း။
text
CLONE VS FORK VS FETCH VS PULL
------------------------------
GITHUB.COM                              YOUR COMPUTER
-----------                             -------------
your-account/repo  <--- fork ---  other/repo
      |
      | clone (once, full copy, local)
      v
  local clone --- fetch --> updates origin/main only
  local clone --- pull  --> fetch + merge into your branch

Fork = account to account, on GitHub only.
Clone / Fetch / Pull = remote to local, on your machine.

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

ဒီသင်ခန်းစာအတွက် demo က bare repository တစ်ခုတည်းကို local clone နှစ်ခုနှင့် သင်နှင့် teammate တစ်ဦးအဖြစ် ကိုယ်စားပြုသုံးထားပြီး၊ GitHub account အစစ် မလိုအပ်ဘဲ အားလုံး အစစ်အမှန် reproducible ဖြစ်ပါတယ်။

Clone တစ်ခုက ဖိုင်တစ်ခု commit လုပ်ပြီး push လုပ်ပါတယ်၊ ဒုတိယ clone (သင့်ကိုယ်စားပြုသော) က အဲဒီ change ကို မမြင်ရသေးပါ။

Fetch

git fetch origin က commit အသစ်ကို download လုပ်ပေမယ့် local main branch ကို မထိပါ — git log main က history ဟောင်းကိုပဲ ပြပြီး git log origin/main က commit အသစ် ရှိနေတာကို ပြပါလိမ့်မယ်၊ merge မလုပ်ရသေးပါဘူး။

Merge

git merge origin/main ကို run လိုက်ရင် conflicting local work မရှိလို့ fast-forward merge ဖြစ်သွားပါတယ်။

Pull (တစ်ဆင့်တည်းသော version)

teammate ရဲ့ ဒုတိယ commit တစ်ခုပြီးနောက် git pull origin main က fetch နှင့် merge ကို အတူတကွလုပ်ပေးပြီး fast-forward အလိုအလျောက် ဖြစ်သွားပါတယ်။

သင့်ကိုယ်တိုင် terminal ထဲမှာ ဒီနည်းလမ်းနှစ်ခုကို နှိုင်းယှဉ်ကြည့်ပါ — fetch တစ်ခုတည်းက working file တွေကို လုံးဝမထိကြောင်း၊ pull ကတော့ ချက်ချင်းပြောင်းလဲစေကြောင်း သတိပြုမိပါလိမ့်မယ်။ ဒီကွာခြားချက်ကပဲ သင်ခန်းစာတစ်ခုလုံးပါပဲ။

အတူတူ စမ်းရေးကြည့်မယ်

bash
git init --bare remote-demo.git
git clone remote-demo.git clone-a
cd clone-a
echo "# Demo Project" > README.md
git add README.md
git commit -m "Initial commit"
git push origin main
cd ..

git clone remote-demo.git clone-b
cd clone-b
echo "Some notes" > notes.md
git add notes.md
git commit -m "Add notes from teammate"
git push origin main
cd ../clone-a

git log --oneline
git fetch origin
git log main --oneline
git log origin/main --oneline
git merge origin/main
git log --oneline

# after a second teammate commit + push:
git pull origin main
git log --oneline
You should see
clone-a ထဲမှာ (fetch မလုပ်ခင်) git log --oneline:
df3882e Initial commit

git fetch origin:
From .../remote-demo
   df3882e..56447b2  main       -> origin/main

git log main --oneline (fetch ပြီးနောက် မပြောင်းလဲ):
df3882e Initial commit

git log origin/main --oneline (commit အသစ်ရှိနေသော်လည်း merge မလုပ်ရသေး):
56447b2 Add notes from teammate
df3882e Initial commit

git merge origin/main:
Updating df3882e..56447b2
Fast-forward
 notes.md | 1 +
 1 file changed, 1 insertion(+)

git log --oneline (merge ပြီးနောက်):
56447b2 Add notes from teammate
df3882e Initial commit

(teammate ဒုတိယ commit ပြီးနောက်) git pull origin main:
From .../remote-demo
   56447b2..9469944  main       -> origin/main
Updating 56447b2..9469944
Fast-forward
 notes.md | 1 +
 1 file changed, 1 insertion(+)

git log --oneline (pull ပြီးနောက်):
9469944 Update notes with second point
56447b2 Add notes from teammate
df3882e Initial commit

၅ မိနစ် စမ်းကြည့်

Repository နှစ်ခု (bare remote တစ်ခုနှင့် clone နှစ်ခု) ကို ကိုယ်တိုင် စမ်းသပ် setup လုပ်ပါ။ clone တစ်ခုမှာ commit လုပ်ပြီး push လုပ်ပါ။ clone အခြားတစ်ခုမှာ git fetch ကို run ပြီး git log main နှင့် git log origin/main ကွာခြားချက်ကို လက်တွေ့ကြည့်ပါ၊ ပြီးမှ merge လုပ်ကြည့်ပါ။

သတိလေးတစ်ချက်

git pull ကို အလိုအလျောက် merge လုပ်ပေးသည်ကို မသိဘဲ run လိုက်ပြီး surprise merge commit ဒါမှမဟုတ် conflict တွေ့တတ်ခြင်း

Contribute လုပ်ချင်တဲ့ project ကို push access မရှိဘဲ တိုက်ရိုက် clone လုပ်ပြီး push ကြိုးစားခြင်း — fork ပြီးမှ ကိုယ်ပိုင် fork ကို clone လုပ်ရမည်ကို မေ့နေခြင်း

GitHub Docs: Getting changes from a remote repositoryGit & GitHub

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • git pull ကို အလိုအလျောက် merge လုပ်ပေးသည်ကို မသိဘဲ run လိုက်ပြီး surprise merge commit ဒါမှမဟုတ် conflict တွေ့တတ်ခြင်း
  • Contribute လုပ်ချင်တဲ့ project ကို push access မရှိဘဲ တိုက်ရိုက် clone လုပ်ပြီး push ကြိုးစားခြင်း — fork ပြီးမှ ကိုယ်ပိုင် fork ကို clone လုပ်ရမည်ကို မေ့နေခြင်း
  • Destructive (သို့) history ပြောင်းလဲနိုင်တဲ့ command တိုင်းကို run မခင် git status နဲ့ လက်ရှိအခြေအနေကို အမြဲစစ်ပါ။

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

Repository နှစ်ခု (bare remote တစ်ခုနှင့် clone နှစ်ခု) ကို ကိုယ်တိုင် စမ်းသပ် setup လုပ်ပါ။ clone တစ်ခုမှာ commit လုပ်ပြီး push လုပ်ပါ။ clone အခြားတစ်ခုမှာ git fetch ကို run ပြီး git log main နှင့် git log origin/main ကွာခြားချက်ကို လက်တွေ့ကြည့်ပါ၊ ပြီးမှ merge လုပ်ကြည့်ပါ။

You'll know it worked when: clone-a ထဲမှာ (fetch မလုပ်ခင်) git log --oneline: df3882e Initial commit git fetch origin: From .../remote-demo df3882e..56447b2 main -> origin/main git log main --oneline (fetch ပြီးနောက် မပြောင်းလဲ): df3882e Initial commit git log origin/main --oneline (commit အသစ်ရှိနေသော်လည်း merge မလုပ်ရသေး): 56447b2 Add notes from teammate df3882e Initial commit git merge origin/main: Updating df3882e..56447b2 Fast-forward notes.md | 1 + 1 file changed, 1 insertion(+) git log --oneline (merge ပြီးနောက်): 56447b2 Add notes from teammate df3882e Initial commit (teammate ဒုတိယ commit ပြီးနောက်) git pull origin main: From .../remote-demo 56447b2..9469944 main -> origin/main Updating 56447b2..9469944 Fast-forward notes.md | 1 + 1 file changed, 1 insertion(+) git log --oneline (pull ပြီးနောက်): 9469944 Update notes with second point 56447b2 Add notes from teammate df3882e Initial commit

Fetch vs Pull vs Clone vs Fork | Thuta Learning