git pull va git fetch — farqi, qachon qaysinisini ishlatish kerak
Muammodan boshlaylik
Ertalab ish boshladingiz. Kecha kechqurun hamkasblaringiz main ga 8 ta commit push qilgan. Sizning lokal main ingiz — eskirgan. Eski kod ustida ish boshlasangiz — keyinroq conflict lar va "bu menda ishlaydi-ku" muammolari.
Yangiliklarni olishning ikki usuli: git fetch — "nima yangi ekanini ko'rish" va git pull — "yangilarini olib, qo'shish". Ular orasidagi farqni tushunish — ko'p chalkashliklardan qutqaradi.
git fetch — faqat yuklab olish
git fetch
remote: Enumerating objects: 23, done.
...
From github.com:otabek/dokon
a3f9c2b..f1e2d3c main -> origin/main
* [new branch] feature/chat -> origin/feature/chat
fetch:
- ✅ Remote dagi yangi commitlarni yuklaydi
- ✅
origin/mainkabi remote-tracking branch larni yangilaydi (19-dars) - ❌ Sizning lokal branch laringizga tegmaydi
- ❌ Ishchi papkadagi fayllarni o'zgartirmaydi
Fetch dan oldin: Fetch dan keyin:
main ●──●──● main ●──●──●
origin/main ●──●──● origin/main ●──●──●──●──●──●
(yangi)
fetch — xavfsiz: hech narsani o'zgartirmaydi, faqat ma'lumot oladi. Uni istalgan vaqtda, istalgancha bajarish mumkin.
Fetch dan keyin — ko'rib chiqish
git status
Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.
git log main..origin/main --oneline # remote da bor, menda yo'q
git diff main origin/main # nima o'zgargan
Ko'rib chiqdingiz, hammasi joyida — endi qo'shish:
git merge origin/main
git pull — fetch + merge
git pull
Bu aslida ikki buyruq:
git pull = git fetch + git merge origin/<joriy-branch>
Updating a3f9c2b..f1e2d3c
Fast-forward
src/chat.js | 120 ++++++++++++++
src/app.js | 4 +-
2 files changed, 122 insertions(+), 2 deletions(-)
Qulay va tez — kundalik ishda eng ko'p ishlatiladi.
Ikki tomonda ham commitlar bo'lsa
Sizda push qilinmagan lokal commitlar bor, remote da ham yangilari bor:
origin/main: ●──●──●──X──Y
main: ●──●──●──A
git pull (merge bilan) — merge commit yaratadi:
●──●──●──X──Y──◆ ← "Merge branch 'main' of github.com:..."
\ /
A────
Kuniga bir necha marta pull qilsangiz — tarix bunday keraksiz merge commitlar bilan to'lib ketadi (17-darsning boshidagi "temir yo'l xaritasi").
git pull --rebase
git pull --rebase
fetch + rebase (merge o'rniga): sizning lokal commitlaringiz remote ning oxiriga qayta qo'yiladi:
●──●──●──X──Y──A' ← to'g'ri chiziq, merge commit yo'q
Bu yerda rebase xavfsiz — chunki faqat sizning hali push qilinmagan commitlaringiz qayta yoziladi (17-darsdagi oltin qoida buzilmaydi).
Standart qilish:
git config --global pull.rebase true
Ko'p jamoalar shuni afzal ko'radi.
[!INFO] Yangi Git versiyalari
pull.rebasesozlanmagan bo'lsa va tarixlar ajralgan bo'lsa ogohlantiradi: "You have divergent branches and need to specify how to reconcile them." Bitta tanlov qiling:git config --global pull.rebase true(rebase) yokifalse(merge).
Faqat fast-forward
git pull --ff-only
Faqat sizda lokal commitlar yo'q bo'lsa ishlaydi; aks holda rad etadi. main kabi branch lar uchun xavfsiz tanlov: siz main ga to'g'ridan-to'g'ri commit qilmaysiz, shuning uchun u har doim fast-forward bo'lishi kerak.
Pull paytidagi conflict
Merge yoki rebase bo'lgani uchun — conflict bo'lishi mumkin. Hal qilish 16 va 17-darslardagidek:
# merge rejimida:
# tahrirlash → git add → git commit
# rebase rejimida:
# tahrirlash → git add → git rebase --continue
# yoki bekor qilish:
git merge --abort # yoki git rebase --abort
Saqlanmagan o'zgarishlar bilan pull
error: Your local changes to the following files would be overwritten by merge:
src/app.js
Please commit your changes or stash them before you merge.
git stash
git pull
git stash pop
Yoki bitta buyruqda:
git pull --rebase --autostash
fetch yoki pull?
| Vaziyat | Buyruq |
|---|---|
| Ertalab, ishni boshlashdan oldin | git pull (yoki git pull --rebase) |
| "GitHub da nima yangi?" — hech narsani o'zgartirmasdan | git fetch + git log ..origin/main |
| Hamkasbning yangi branch ini olish | git fetch + git switch branch-nomi |
| Ko'rib chiqmasdan olishdan qo'rqasiz | git fetch → ko'rib chiqish → git merge |
| Barcha remote lar va eskirgan branch larni tozalash | git fetch --all --prune |
| Push rad etildi | git pull (yoki --rebase), keyin git push |
[!TIP] Yangi feature branch boshlashdan oldin har doim:
git switch main && git pull— keyingit switch -c feature/.... Eskirganmaindan boshlangan branch — keyingi conflict larning eng keng tarqalgan sababi.
Feature branch ni yangilash
Siz feature/savat dasiz, main da yangi commitlar bor:
git fetch
git rebase origin/main # yoki: git merge origin/main
Lokal main ga o'tish shart emas — origin/main ga to'g'ridan-to'g'ri murojaat qilish mumkin.
Nima uchun shunday?
Nima uchun Git ikki alohida buyruqqa ega — pull yetarli emasmi?
Chunki "ma'lumot olish" va "o'z ishingizni o'zgartirish" — turli xavf darajasidagi ikki harakat. fetch — faqat o'qiydi: u hech qachon conflict keltirmaydi, ishingizni buzmaydi. U sizga qaror qabul qilishdan oldin ma'lumot beradi: hamkasblar nima qildi, mening ishimga ta'sir qiladimi, conflict bo'ladimi? pull esa qarorni darhol qabul qiladi. Ko'p tajribali dasturchilar aynan shuning uchun fetch + ko'rib chiqish + merge/rebase ni afzal ko'radi: hech qanday kutilmagan hodisa yo'q. pull — ishonch bilan, kundalik oddiy holatlar uchun qisqa yo'l.
Xulosa
Eslab qoling:
git fetch— yuklab olish,origin/*ni yangilash; lokal branch larga tegmaydi; xavfsizgit pull=fetch+mergegit pull --rebase— merge commitlarsiz, to'g'ri chiziqli tarix;pull.rebase truegit pull --ff-only—mainuchun xavfsiz- Fetch dan keyin:
git log main..origin/main,git diff main origin/main - Saqlanmagan o'zgarishlar —
stashyoki--autostash - Yangi branch dan oldin:
git switch main && git pull git fetch --prune— o'chirilgan remote branch larni tozalash
Keyingi dars
23-dars: Pull Request — nima, qanday ochiladi, code review jarayoni