Mundarija (40)
- Bu darsda
- 1. Nega bu kerak?
- 2. Sozlama qayerdan keladi
- 2.1 Uch daraja va yangi sintaksis
- 2.2 Kim yutdi: --show-origin
- 3. Alias: o'z buyruqlaringiz
- 3.1 Oddiy alias
- 3.2 ! bilan alias
- 4. includeIf: ish va shaxsiy akkaunt
- 4.1 Muammo
- 4.2 gitdir: — papka bo'yicha
- 4.3 Ikki tuzoq: oxirgi / va katta harf
- 4.4 hasconfig: — remote manzili bo'yicha
- 5. Kundalik tezlashtirgichlar
- 5.1 push.autoSetupRemote
- 5.2 fetch.prune
- 5.3 help.autocorrect
- 6. Konflikt va diff sozlamalari
- 6.1 merge.conflictstyle zdiff3
- 6.2 rerere — yechimni eslab qolish
- 6.3 diff.algorithm histogram
- 7. Katta repoda tezlik
- 7.1 Kanon tajribasi: git status
- 7.2 Commit-graph
- 7.3 git maintenance va bitta topilma
- 8. Muharrirda: GitLens
- 9. Loyiha qadami: o'z sozlamangiz
- 10. Ko'p uchraydigan xatolar
- 10.1 includeIf jim ishlamaydi
- 10.2 Commit allaqachon noto'g'ri email bilan
- 10.3 Alias o'rnatilgan buyruq nomi bilan
- 10.4 autocorrect immediate noto'g'ri buyruqni bajardi
- 10.5 rerere noto'g'ri yechimni eslab qoldi
- 11. Mashqlar
- 1-mashq (oson): bo'shliqlarni to'ldiring
- 2-mashq (o'rta): qaysi qiymat yutdi?
- 3-mashq (qiyin): ikki papka, ikki email
- 12. Real ishda
- Xulosa
- Manbalar
Git konfiguratsiyasi: alias, includeIf, rerere va unumdorlik sozlamalari
Qisqacha: Git'ning yuzlab sozlamasi bor, lekin kundalik ishni bir nechtasi o'zgartiradi. Alias uzun buyruqni qisqa nomga aylantiradi. Shartli qo'shish (
includeIf) esa ish papkasidagi repolarga ish emailini, qolganlariga shaxsiy emailni avtomatik qo'yadi. Sozlamapush.autoSetupRemoteyangi branch'ni birinchigit pushdayoq yuboradi,fetch.pruneserverda o'chirilgan branch'larni tozalaydi. Yana biri —rerere: bir marta yechilgan konfliktni eslab qoladi,zdiff3esa asl versiyani ham ko'rsatadi. Katta repodacore.untrackedCache,core.fsmonitorvagit maintenancetezlikka yordam beradi. Kanon tajribasida 40 ming faylli repodagit status95 ms dan 83 ms gacha tushdi.
Bu darsda
- Sozlamani qaysi daraja berganini
--show-scopeva--show-originbilan aniqlaysiz. - Oddiy va
!li alias yozasiz. includeIfbilan ish va shaxsiy repolarga turli email qo'yasiz va uning tuzoqlarini bilasiz.push.autoSetupRemote,fetch.prune,help.autocorrect,zdiff3,rererevahistogramni sinab, natijasini ko'rasiz.- Katta repoda
git statusva xizmat ishlarini (git maintenance) qanday tezlashtirishni tushuntirasiz.
Oldin bilishingiz kerak: Git'ni o'rnatish va birinchi sozlash, Tarixni o'qish: git log, Conflictlarni yechish amaliyoti, Remote: clone, fetch, pull, push, Katta repolar.
1. Nega bu kerak?
Git'ni o'rnatish darsida uchta sozlama yozgansiz: ism, email va main. O'shandan beri Git sizdan bir necha marta "boshqacha qilaymi?" deb so'radi. Yangi branch'ni push qilganingizda --set-upstream ni talab qildi. Konfliktda faqat ikki tomonni ko'rsatdi, asl matnni emas. Ishxona repo'siga shaxsiy emailingiz bilan commit tushdi.
Bularning hammasi — sukut qiymatlar. Git ularni ehtiyotkorlik bilan tanlagan: eski xulqni buzmaslik uchun. Siz esa o'z ishingizga mos qiymatni bir marta yozib qo'yasiz va har kuni foydasini ko'rasiz.
Hayotiy o'xshatish: yangi telefon. Zavod sozlamasida u ishlaydi, lekin klaviatura tili, yorqinlik, bildirishnomalar — har kim o'ziga moslaydi. Bir soatlik sozlash keyingi ikki yilni qulay qiladi. Git ham shunday — faqat sozlash bir soat emas, o'n daqiqa.
Bu dars — tajriba darsi. vazifalar-api kodi o'zgarmaydi, commit yo'q. Hamma buyruqni biz vaqtinchalik papkada ishga tushirdik: kompyuterning umumiy sozlamasiga tegmaslik uchun GIT_CONFIG_GLOBAL boshqa faylga qaratildi (Git'ni o'rnatish darsidagi usul). Hash va yo'llar sizda boshqacha chiqadi.
2. Sozlama qayerdan keladi
2.1 Uch daraja va yangi sintaksis
Takrorlaymiz: sozlama uch darajada yashaydi — system (butun kompyuter), global (sizning foydalanuvchingiz, ~/.gitconfig) va local (bitta repo, .git/config). Bir xil kalit bir necha joyda bo'lsa, yaqinrog'i yutadi: local → global → system.
Yangi Git versiyalarida git config ga aniq buyruqlar qo'shildi: get, set, list, unset. Eski shakl (git config user.email) ham ishlaydi, lekin yangisi o'qishga tushunarliroq. Git'ning o'z maslahatlari ham endi shu shaklda chiqadi — Jamoa workflow'lari darsidagi git config set advice.diverging false ni eslang.
git config set alias.st "status -sb"
git config get alias.st
git config get --show-scope user.email
git config get nomalum.kalit; echo "exit $?"Terminalda:
status -sb
global aziz@example.com
exit 1set jim ishladi (chiqish kodi 0). --show-scope qiymat oldiga darajani yozdi: email global sozlamadan kelyapti. Yo'q kalitda get hech narsa yozmaydi, faqat 1 qaytaradi — skriptda shunga tayanish mumkin.
2.2 Kim yutdi: --show-origin
Bitta kalit bir necha fayldan kelishi mumkin. Shunda --all hammasini, --show-origin esa fayl yo'lini ko'rsatadi. Bu buyruqni «includeIf» bo'limida ko'p ishlatamiz:
flowchart LR
S["system<br/>(kompyuter)"] --> G["global<br/>~/.gitconfig"]
G --> I["includeIf fayli<br/>(shart bajarilsa)"]
I --> L["local<br/>.git/config"]
L --> N["git config get<br/>oxirgisi yutadi"]Diagrammani chapdan o'ngga o'qing. Git fayllarni shu tartibda o'qiydi, keyingisi oldingisini bosib o'tadi. includeIf fayli global faylning ichiga ulanadi — u global darajada, lekin o'zidan oldingi qatorlardan keyin turadi.
3. Alias: o'z buyruqlaringiz
3.1 Oddiy alias
Tarixni o'qish darsida git lg ni yaratgansiz. Alias — alias.<nom> sozlamasi: qiymati git dan keyingi so'zlar. Biz uchtasini yozdik:
git config set alias.lg "log --oneline --graph --decorate -5"
git config set alias.oxirgi "log -1 --format='%h %an: %s'"
git st
git lg
git oxirgi## main
* 88b1656 (HEAD -> main) feat: boshlang'ich
88b1656 Aziz Karimov: feat: boshlang'ichgit st — status -sb: qisqa holat va branch nomi bitta qatorda. git oxirgi — oxirgi commit qisqa ko'rinishda. Alias nimaga teng ekanini unutsangiz, Git o'zi aytadi:
git help st'st' is aliased to 'status -sb'Hamma alias ro'yxati — git config get --all --show-names --regexp '^alias\.'.
3.2 ! bilan alias
Qiymat ! bilan boshlansa, Git uni shell buyrug'i sifatida ishga tushiradi. Shunda bir nechta buyruqni birlashtirish va argument olish mumkin:
git config set alias.yangi \
'!f() { git switch -c "$1" && git push -u origin "$1"; }; f'git yangi docs/readme — branch ochadi va darhol yuboradi. f() { …; }; f — bash funksiyasi: $1 birinchi argument (Shell skript yozish asoslari darsi).
Diqqat:
!li alias — oddiy shell skript. Begona odam bergan.gitconfigni ko'r-ko'rona nusxalamang: unda istalgan buyruq yashirinishi mumkin. Har alias'ni o'qib, tushunib qo'shing.
Alias'ni faqat buyruqni tushunganingizdan keyin yarating. Boshqa kompyuterda yoki hamkasb bilan ishlaganda to'liq buyruqni bilishingiz kerak bo'ladi.
4. includeIf: ish va shaxsiy akkaunt
4.1 Muammo
SSH kalit darsida ikki GitHub akkaunti uchun ikki kalit sozlagansiz va va'da bergan edik: har repoda alohida emailni avtomatlashtiramiz. Muammo shunday: global user.email — bitta. Ish repo'sida har safar git config user.email … yozishni unutasiz, va kompaniya tarixiga shaxsiy emailingiz tushadi.
Yechim — shartli qo'shish (includeIf): "repo shu papkada bo'lsa, mana bu faylni ham o'qi".
4.2 gitdir: — papka bo'yicha
Ish loyihalari ~/ish/ da, shaxsiylari boshqa joyda deylik. Global faylga bitta shart, ish uchun alohida fayl:
git config --global includeIf."gitdir:~/ish/".path \
"~/.gitconfig-ish"
git config --file ~/.gitconfig-ish \
user.email "aziz@kompaniya.example.com"--file — ixtiyoriy faylga yozish. Natijada ~/.gitconfig (bizning sinovdagi to'liq mazmuni):
[user]
name = Aziz Karimov
email = aziz@example.com
[init]
defaultBranch = main
[core]
autocrlf = false
[includeIf "gitdir:~/ish/"]
path = ~/.gitconfig-ishEndi ikki repo ochib, emailni so'raymiz:
git init -q ~/ish/vazifalar-api
git init -q ~/shaxsiy/portfolio
for r in ish/vazifalar-api shaxsiy/portfolio; do
echo "$r: $(git -C ~/$r config user.email)"
doneish/vazifalar-api: aziz@kompaniya.example.com
shaxsiy/portfolio: aziz@example.comgit -C <papka> — buyruqni o'sha papkada bajarish (cd qilmasdan). Ish repo'si o'z emailini oldi. Nega? --show-origin ko'rsatadi (uy papkasi yo'li ~ ga qisqartirildi):
git -C ~/ish/vazifalar-api config get --all --show-origin \
user.emailfile:~/.gitconfig aziz@example.com
file:~/.gitconfig-ish aziz@kompaniya.example.comIkkala qiymat ham bor. Ikkinchisi keyin o'qilgani uchun yutadi — «Kim yutdi» bo'limidagi diagramma aynan shu.
4.3 Ikki tuzoq: oxirgi / va katta harf
Biz shartni ikki xil "deyarli to'g'ri" yozib ko'rdik:
slash'siz: aziz@example.com
gitdir:~/ISH/ -> aziz@example.com
gitdir/i:~/ISH/ -> aziz@kompaniya.example.com- Oxirgi
/siz (gitdir:~/ish) — ishlamadi. Shart.gitpapkasining yo'liga qaraydi: u~/ish/vazifalar-api/.git. Git hujjatiga ko'ra, naqsh/bilan tugasa, oxiriga**qo'shiladi — "shu papka ichidagi hamma narsa"./siz naqsh faqat aniq shu yo'lga mos keladi. - Katta harf (
gitdir:~/ISH/) — ishlamadi.gitdir:katta-kichik harfni farqlaydi. Windows'da papka nomiIshyokiishbo'lishi mumkin, fayl tizimi ularni bir xil ko'radi, Git esa yo'q.gitdir/i:— harfga qaramaydigan shakl. Windows va macOS'da shuni yozing.
Ikkala holatda ham xato xabari chiqmadi — Git jim global emailni qo'ydi. Shuning uchun sozlagandan keyin doim ish papkasidagi repoda git config get --show-origin user.email bilan tekshiring.
4.4 hasconfig: — remote manzili bo'yicha
Ba'zan loyihalar papka bo'yicha emas, tashkilot bo'yicha ajraladi. Shart remote URL'iga ham qaray oladi:
K='includeIf.hasconfig:remote.*.url:'
K+='https://github.com/kompaniya/**.path'
git config --global "$K" '~/.gitconfig-ish'Biz ikki repo yaratib, ularga remote qo'shdik:
portfolio: aziz@example.com
boshqa/api: aziz@kompaniya.example.comboshqa/api ish papkasida emas, lekin remote'i github.com/kompaniya/ da — ish emaili qo'yildi. Bu shart git clone dan keyin ishlaydi: remote qo'shilmagan yangi git init repo hali hech qaysi shartga mos emas.
Tekshirib ko'ring:
includeIf "gitdir:~/ish/"ni global faylning boshiga,[user] email = aziz@example.comdan oldin yozdingiz. Ish repo'sida qaysi email chiqadi?
Javob
Shaxsiy email — aziz@example.com. Git faylni yuqoridan pastga o'qiydi va bir xil kalitda oxirgisi yutadi. Ulangan fayl o'z joyida o'qiladi: avval ish emaili, keyin pastdagi [user] uni bosib o'tadi. Shuning uchun includeIf qatorlari global faylning oxirida tursin. git config --global bilan qo'shsangiz, Git ularni o'zi oxiriga yozadi.
5. Kundalik tezlashtirgichlar
5.1 push.autoSetupRemote
Remote darsidan tanish xato — yangi branch'ning birinchi push'i:
git switch -c feature/filtr
# ... commit
git pushfatal: The current branch feature/filtr has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature/filtr
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'."Joriy branch'ning upstream'i yo'q." Xabarning o'zi yechimni aytyapti — push.autoSetupRemote. Yoqamiz va xuddi shu git push:
git config set push.autoSetupRemote true
git pushTo ../server.git
* [new branch] feature/filtr -> feature/filtr
branch 'feature/filtr' set up to track 'origin/feature/filtr'.Branch yuborildi va kuzatuv (tracking) o'zi sozlandi. Sinovda remote — lokal "bare" repo (../server.git), GitHub'da xuddi shunday ishlaydi. GitHub flow'da har ish yangi branch (Jamoa workflow'lari) — bu sozlama kuniga bir necha marta vaqt tejaydi.
5.2 fetch.prune
PR merge bo'lgach, branch serverda o'chiriladi. Lekin sizning kompyuteringizdagi origin/feature/filtr nusxasi qoladi. Biz Nodira nomidan serverdagi branch'ni o'chirdik, keyin Aziz git fetch qildi:
origin/HEAD -> origin/main
origin/feature/filtr
origin/maingit fetch jim o'tdi, git branch -r esa o'lik branch'ni ko'rsatyapti. Bir necha oyda bunday "arvoh"lar o'nlab bo'ladi. fetch.prune bilan:
git config set fetch.prune true
git fetchFrom ../server
- [deleted] (none) -> origin/feature/filtrServerda yo'q branch'ning lokal nusxasi o'chdi. Bu faqat origin/… ko'rsatkichlariga tegadi — sizning lokal branch'laringiz (feature/filtr) o'chmaydi. Ularni tozalash — Pull Request darsidagi git branch -d retsepti.
5.3 help.autocorrect
Buyruqni xato yozdingiz: git sttaus. Sukut bo'yicha Git taklif beradi va to'xtaydi:
git: 'sttaus' is not a git command. See 'git --help'.
The most similar command is
statushelp.autocorrect buni o'zgartiradi. Biz qiymatlarni sinadik, jadval Git 2.54 hujjati bilan ham solishtirildi. Tuzoqqa e'tibor bering: 1 "0.1 soniya" emas — hujjatga ko'ra u immediate bilan bir xil (biz sinadik: kutmasdan bajardi):
| Qiymat | Nima bo'ladi |
|---|---|
0 yoki show (sukut) |
taklif ko'rsatadi, bajarmaydi |
immediate yoki 1 |
darhol bajaradi |
10 (1 dan katta son) |
1.0 soniya kutib bajaradi (o'ndan bir soniyalarda) |
never |
taklif ham ko'rsatmaydi |
prompt |
"bajaraymi?" deb so'raydi |
immediate dagi chiqish:
WARNING: You called a Git command named 'sttaus', which does not exist.
Continuing under the assumption that you meant 'status'.
On branch main
nothing to commit, working tree clean"Mavjud bo'lmagan buyruqni chaqirdingiz. status demoqchi edingiz, deb davom etyapman." Qulay — lekin xavfli tomoni ham bor. Biz git comit -m "x" yozdik va Git uni so'ramasdan commit sifatida bajardi. Bu safar commit qiladigan narsa yo'q edi. Lekin xuddi shunday push yoki reset ham so'roqsiz ishga tushadi.
Tavsiya: prompt — Git taklifni aytadi va tasdiq kutadi. Bu rejimni terminalsiz (skriptda) sinadik: so'rash imkoni bo'lmagani uchun Git buyruqni bajarmadi. Terminaldagi so'rov ko'rinishini biz sinamadik (sinalmagan, 2026-11).
6. Konflikt va diff sozlamalari
6.1 merge.conflictstyle zdiff3
Conflictlarni yechish darsidagi belgilar bilan konflikt. Asl qator narx: 25000 edi; main da 28 000 ga, branch'da 30 000 ga o'zgardi. Sukut ko'rinish:
<<<<<<< HEAD
narx: 28000
=======
narx: 30000
>>>>>>> feature/narx
vaqt: 09:00Qaysi biri to'g'ri? Bu ko'rinishdan bilib bo'lmaydi: ikkalasi ham asldan o'zgarganmi yoki biri eski qiymatmi — noma'lum. zdiff3 bilan:
git config set merge.conflictstyle zdiff3
git merge feature/narx<<<<<<< HEAD
narx: 28000
||||||| e2e0cc1
narx: 25000
=======
narx: 30000
>>>>>>> feature/narx
vaqt: 09:00||||||| dan keyin — asos (ikki tarix ajralgan commit, e2e0cc1). Endi rasm aniq: ikkala tomon ham 25 000 ni o'zgartirgan. Bu — "biri eskirgan" emas, haqiqiy kelishmovchilik: kim haq ekanini odamdan so'rash kerak. zdiff3 dagi z — ikki tomonda bir xil bo'lgan qatorlarni konflikt hududidan chiqarib tashlaydi, blok kichikroq bo'ladi.
6.2 rerere — yechimni eslab qolish
Rerere — "reuse recorded resolution", ya'ni "yozib olingan yechimni qayta ishlat". Bir xil konfliktni ikkinchi marta yechmaslik uchun. Qachon kerak? Masalan, uzoq branch'ni rebase qilasiz, bekor qilasiz, keyin qaytadan qilasiz — har safar o'sha konflikt. Yoqamiz va konfliktni bir marta yechamiz:
git config set rerere.enabled true
git merge feature/narx
# menyu.txt da 30000 ni qoldirdik
git add menyu.txt && git commit --no-editCONFLICT (content): Merge conflict in menyu.txt
Recorded preimage for 'menyu.txt'
Automatic merge failed; fix conflicts and then commit the result.
Recorded resolution for 'menyu.txt'.Ikki yangi qator: "konflikt holati yozib olindi" va commitda "yechim yozib olindi". Endi merge'ni bekor qilib (git reset --hard HEAD~1), qaytadan merge qilamiz:
CONFLICT (content): Merge conflict in menyu.txt
Resolved 'menyu.txt' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result."Oldingi yechim bilan hal qilindi." Fayl ichida — narx: 30000, belgilarsiz. Lekin git status --short hali UU menyu.txt deydi: rerere faylni tuzatdi, lekin git add ni sizga qoldirdi. Bu ataylab: avtomatik yechimni ko'zdan kechiring, keyin add. Avtomatik add kerak bo'lsa — rerere.autoUpdate true (Git hujjati).
6.3 diff.algorithm histogram
Diff — "nima o'zgardi" degan savolga javob. Bir xil o'zgarishni turli algoritm turlicha ko'rsatadi. Biz ikki funksiyaning o'rnini almashtirdik — boshqa hech narsa o'zgarmadi. Sukut algoritm (myers):
@@ -1,13 +1,13 @@
-function narx(son) {
+function vaqt(son) {
if (son > 0) {
- return son * 25000;
+ return son * 60;
}
return 0;
}
-function vaqt(son) {
+function narx(son) {
if (son > 0) {
- return son * 60;
+ return son * 25000;
}
return 0;
}Bu diff'ni o'qisangiz, ikkala funksiya "tahrirlangan"dek ko'rinadi: nom va son o'zgargan. Aslida esa funksiyalar faqat joy almashgan. Histogram:
@@ -1,13 +1,13 @@
-function narx(son) {
- if (son > 0) {
- return son * 25000;
- }
- return 0;
-}
-
function vaqt(son) {
if (son > 0) {
return son * 60;
}
return 0;
}
+
+function narx(son) {
+ if (son > 0) {
+ return son * 25000;
+ }
+ return 0;
+}Endi aniq: narx tepadan olindi va pastga qo'yildi, vaqt tegilmagan. Qator soni ko'proq, lekin ma'no to'g'ri. Myers } va return 0; kabi ko'p takrorlanadigan qatorlarni bir-biriga bog'lab yubordi. Histogram esa avval kam uchraydigan qatorlardan "langar" tanlaydi.
git config --global diff.algorithm histogramBu sozlama git diff, git log -p, git show ga ta'sir qiladi. Review'da diff'ni hamkasbingiz o'qiydi — qanchalik aniq bo'lsa, shuncha tez tushunadi.
7. Katta repoda tezlik
7.1 Kanon tajribasi: git status
Katta repolar darsida klon hajmini o'rgangan edik. Endi kundalik buyruqlar tezligi. Kanon sun'iy repo yaratdi: 40 001 fayl, 2 001 commit, 300 ta kuzatilmagan fayl. git status ni har sozlamada 5 marta o'lchab, medianasini oldi. Faqat shu repo'ning local sozlamasi o'zgartirildi.
- sukut95 ms
- core.untrackedCache92 ms
- + core.fsmonitor83 ms
Manba: IlmHamroh kanon tajribasi, 2026-11-04: Git 2.54.0.windows.1, bitta mashina, NTFS kesh issiq; nisbat muhim
core.untrackedCache— kuzatilmagan fayllar ro'yxatini keshlaydi: har safar hamma papkani qayta ko'rmaydi. 95 → 92 ms.core.fsmonitor— fon jarayoni (daemon) fayl tizimidagi o'zgarishlarni kuzatadi.git status40 ming faylni tekshirish o'rniga "nima o'zgardi?" deb so'raydi. 92 → 83 ms. Windows va macOS uchun Git'da o'rnatilgan daemon bor; kanon uni Windows'da sinadi va oxirida to'xtatdi (git fsmonitor--daemon stop).
Farq atigi 13 % — kutganimizdan kam. Sabab: bitta mashina, fayllar operatsion tizim keshida "issiq". Sovuq diskda va yuz minglab faylda farq kattaroq bo'lishi mumkin — lekin buni biz o'lchamadik. Xulosa halol: o'lchamasdan yoqmang. Avval time git status, keyin sozlama, keyin yana o'lchov.
Git'da bir nechta sozlamani birdaniga yoqadigan bayroq bor — feature.manyFiles. Git 2.54 hujjatiga ko'ra u core.untrackedCache, indeksning ixcham formatini (index.version=4) va indeksni tezroq yozishni (index.skipHash) yoqadi. Biz uni o'lchamadik (sinalmagan, 2026-11).
7.2 Commit-graph
Commit-graph — commitlar orasidagi bog'lanishlarni alohida faylda saqlaydigan indeks. Katta tarixda git log --graph ni tezlashtiradi. Kanon o'lchovi (2 000 commit, fayl 120 KB):
| Buyruq | commit-graph yo'q | bor |
|---|---|---|
git log --graph --oneline |
136 ms | 145 ms |
git rev-list --count HEAD |
72 ms | 69 ms |
Foyda ko'rinmadi — 2 000 commit uning uchun kichik. Yuz minglab commitli repolarda (Linux yadrosi kabi) farq katta bo'ladi deyiladi, lekin bu sinalmagan. Saboq o'sha: sozlama "tezlashtiradi" degan va'da emas, o'lchov bilan tasdiqlanadigan faraz.
7.3 git maintenance va bitta topilma
Vaqt o'tishi bilan .git ichida minglab mayda fayl to'planadi — alohida obyektlar (loose object) (Git ichkaridan darsi). Ularni pack faylga yig'ish — git gc yoki zamonaviy git maintenance run.
Kanon 40 203 ta alohida obyektli repoda to'liq ro'yxatni (gc, commit-graph, loose-objects, incremental-repack) ishga tushirdi. Natija: 580 soniya ichida tugamadi — vaqt chegarasi to'xtatdi. Windows'da har obyekt alohida fayl, antivirus har birini tekshiradi. Keyin faqat ikkita yengil vazifa: --task=loose-objects --task=commit-graph — 7.7 soniya.
Lekin natijada g'alati narsa bor edi: hamma obyekt pack'ga yig'ildi (in-pack: 46203), alohida fayllar esa o'chmadi (count hali 40 203), .git hajmi 63 MB dan 66 MB ga o'sdi. Xatomi? Biz kichik repoda (2 000 obyekt) takrorladik:
git maintenance run --task=loose-objects
git maintenance run --task=loose-objectsoldin: count: 2000 in-pack: 0
1-yugurish: count: 2000 in-pack: 2000
2-yugurish: count: 0 in-pack: 2000 Xato emas — dizayn. Git hujjatiga ko'ra, loose-objects vazifasi ikki qadamda ishlaydi: avval allaqachon pack'da bor alohida obyektlarni o'chiradi, keyin qolganlarini yangi pack'ga yig'adi. Birinchi yugurishda pack'da hech narsa yo'q edi — faqat yig'di. Ikkinchisida o'chirdi. Shunday qilinishi parallel ishlayotgan boshqa git buyruqlarini buzmaslik uchun: obyekt hech qachon "yo'q" bo'lib qolmaydi.
git maintenance start bu vazifalarni fonda soatlik, kunlik va haftalik jadval bilan ishga tushiradi — Windows'da schtasks (Task Scheduler) orqali (Git hujjati). Bu tizim sozlamasi bo'lgani uchun kanon uni ishlatmadi (sinalmagan). O'z kompyuteringizda katta repo bo'lsa — urinib ko'ring, git maintenance stop bilan o'chiriladi.
8. Muharrirda: GitLens
Ko'p dasturchilar Git tarixini VS Code ichida ko'radi. GitLens — eng mashhur kengaytmalardan biri: har qator yonida "kim, qachon, qaysi commit" (inline blame), fayl tarixi, branch'lar grafigi. Bu Kod arxeologiyasi darsidagi git blame va git log -L ning grafik ko'rinishi — ichida o'sha buyruqlar ishlaydi.
Biz GitLens'ni sinamadik (sinalmagan, 2026-11). Uning ba'zi imkoniyatlari pullik obuna bilan. VS Code'ning o'zida ham Source Control paneli va "Timeline" bor — ular bepul.
Muhimi: kengaytma terminal buyruqlarining o'rnini bosmaydi. Serverda, CI'da yoki hamkasb kompyuterida faqat terminal bo'ladi.
9. Loyiha qadami: o'z sozlamangiz
Bu dars — tajriba darsi: vazifalar-api o'zgarmaydi, commit yo'q. Lekin o'z kompyuteringizning global sozlamasini yangilashni tavsiya qilamiz. Biz tajribada sinagan sozlamalar:
git config --global push.autoSetupRemote true
git config --global fetch.prune true
git config --global merge.conflictstyle zdiff3
git config --global rerere.enabled true
git config --global diff.algorithm histogram
git config --global help.autocorrect prompt
git config --global alias.st "status -sb"
git config --global alias.lg \
"log --oneline --graph --decorate -20"Ishxona va shaxsiy loyihalaringiz bo'lsa — includeIf ni qo'shing (Windows'da gitdir/i:):
git config --global includeIf."gitdir/i:~/ish/".path \
"~/.gitconfig-ish"
git config --file ~/.gitconfig-ish user.email "ish@emailingiz"Keyin tekshiruv: vazifalar-api papkasida git config get --show-origin user.email — kutgan emailingiz va kutgan faylingiz chiqsin. Global faylingizni Git'ni o'rnatish darsidagidek git config --global --edit bilan ochib, ko'zdan kechiring.
Hammasini birdaniga yoqish shart emas. Bittadan qo'shing va bir hafta ishlating: qaysi biri haqiqatan yordam berayotganini o'zingiz sezasiz.
10. Ko'p uchraydigan xatolar
10.1 includeIf jim ishlamaydi
Eng ko'p uchraydigan holat. Xato xabari yo'q, faqat noto'g'ri email. Uch sabab: naqsh oxirida / yo'q; Windows'da harf farqi (gitdir/i: kerak); includeIf fayl boshida turibdi va pastdagi [user] uni bosib o'tadi. Tekshirish yo'li bitta: ish repo'sida git config get --all --show-origin user.email.
10.2 Commit allaqachon noto'g'ri email bilan
includeIf faqat keyingi commitlarga ta'sir qiladi. Push qilinmagan oxirgi commitni tuzatish: git commit --amend --reset-author --no-edit (Xatoni tuzatish 1 darsidagi amend). Push qilinganini qayta yozish — Tarixni qayta yozish darsidagi ehtiyot choralari bilan.
10.3 Alias o'rnatilgan buyruq nomi bilan
git config set alias.status "status -sb" — Git uni e'tiborsiz qoldiradi: o'rnatilgan buyruq har doim alias'dan ustun. Alias'ga yangi nom bering (st).
10.4 autocorrect immediate noto'g'ri buyruqni bajardi
«help.autocorrect» bo'limidagi comit misoli. Davosi — prompt yoki sukut qiymat. Shoshilganda tezlik emas, xavfsizlik muhim.
10.5 rerere noto'g'ri yechimni eslab qoldi
Konfliktni xato yechib, keyin tuzatdingiz — rerere esa birinchisini eslab qolgan bo'lishi mumkin. Unutdirish: git rerere forget <fayl> (konflikt holatida) — biz sinadik, Git "Forgot resolution for 'menyu.txt'" deb javob berdi. Shuning uchun rerere git add ni sizga qoldiradi — natijani ko'rib tasdiqlang.
11. Mashqlar
Mashqlar kurs/mashqlar/32/08-sozlama/ da. 2-mashq yechimi Node 24.21.0 da, 3-mashq yechimi Git 2.54.0 da tekshirilgan (biz ishga tushirdik).
1-mashq (oson): bo'shliqlarni to'ldiring
- Yangi branch'ni birinchi
git pushdayoq kuzatuv bilan yuboradigan sozlama —push. - Serverda o'chirilgan branch'larning lokal nusxasini
fetchda tozalaydigan sozlama —fetch. - Konfliktda asos versiyasini ham ko'rsatadigan uslub —
merge.conflictstyle - Bir marta yechilgan konfliktni eslab qoladigan sozlama —
rerere. - Windows'da harf farqiga qaramaydigan papka sharti —
includeIf ":~/ish/"
Yechim
- autoSetupRemote —
--set-upstreamni har safar yozmaslik uchun. - prune — faqat
origin/…ko'rsatkichlari o'chadi, lokal branch'lar qoladi. - zdiff3 —
|||||||dan keyin asl qator. - enabled — yechim
.git/rr-cacheda saqlanadi. - gitdir/i —
i— "ignore case", harfga qaramaslik.
2-mashq (o'rta): qaysi qiymat yutdi?
golibniTop(qatorlar, kalit) funksiyasini yozing. Kirish — git config list --show-scope chiqishining qatorlari: daraja + tab + kalit=qiymat. Funksiya berilgan kalitning yutgan qiymatini, uning darajasini va bosib o'tilgan qiymatlar ro'yxatini qaytarsin. Kalit topilmasa — null. Ishora: oxirgi mos qator yutadi. Qatorni split("\t") bilan, kalit=qiymat ni birinchi = bo'yicha bo'ling — qiymat ichida ham = bo'lishi mumkin: indexOf va slice (Kesish, bo'lish va to'ldirish).
Yechim
function golibniTop(qatorlar, kalit) {
const mos = [];
for (const q of qatorlar) {
const [daraja, juft] = q.split("\t");
const i = juft.indexOf("=");
if (juft.slice(0, i) === kalit) {
mos.push({ daraja, qiymat: juft.slice(i + 1) });
}
}
if (mos.length === 0) return null;
const golib = mos.at(-1);
const bosilgan = mos.slice(0, -1).map(
(m) => `${m.daraja}: ${m.qiymat}`,
);
return { ...golib, bosilgan };
}
const qatorlar = [
"global\tuser.name=Aziz Karimov",
"global\tuser.email=aziz@example.com",
"global\tuser.email=aziz@kompaniya.example.com",
"global\talias.yangi=!f() { a=1; }; f",
"local\tcore.bare=false",
];
console.log(golibniTop(qatorlar, "user.email"));
console.log(golibniTop(qatorlar, "alias.yangi").qiymat);
console.log(golibniTop(qatorlar, "pull.rebase"));Konsolda:
{
daraja: 'global',
qiymat: 'aziz@kompaniya.example.com',
bosilgan: [ 'global: aziz@example.com' ]
}
!f() { a=1; }; f
nullIkkinchi email includeIf faylidan kelgan, lekin darajasi baribir global — «includeIf» bo'limidagi --show-scope chiqishi kabi. Alias qiymatidagi ikkinchi = buzilmadi, chunki faqat birinchisi bo'yicha bo'ldik. mos.at(-1) — oxirgi element.
3-mashq (qiyin): ikki papka, ikki email
Vaqtinchalik papkada butun sozlamani noldan quring. Uy papkasi (HOME) va global fayl shu papkaga qaratilsin — haqiqiy sozlamangizga tegmasin. Talablar: global email aziz@example.com; ~/ish/ ichidagi repolar uchun aziz@kompaniya.example.com (harfga qaramaydigan shart); oxirgi alias'i — %h %ae: %s formatida oxirgi commit. Keyin ish/api va shaxsiy/sayt repolarida bittadan commit qilib, git oxirgi ni chiqaring. Oxirida papkani o'chiring.
Ishora: export HOME=$PWD — shu sessiya uchun ~ shu papkaga ochiladi. SHA'lar darsdagidek chiqishi uchun sanani qotiring: GIT_AUTHOR_DATE va GIT_COMMITTER_DATE (Bisect darsidagi skriptlar kabi).
Yechim
mkdir sozlama-sinov && cd sozlama-sinov
export HOME=$PWD
export GIT_CONFIG_GLOBAL=~/.gitconfig
git config --global user.name "Aziz Karimov"
git config --global user.email "aziz@example.com"
git config --global init.defaultBranch main
git config --global alias.oxirgi "log -1 --format='%h %ae: %s'"
git config --global includeIf."gitdir/i:~/ish/".path \
"~/.gitconfig-ish"
git config --file ~/.gitconfig-ish \
user.email "aziz@kompaniya.example.com"
export GIT_AUTHOR_DATE="2026-11-04T10:00:00+05:00"
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
for r in ish/api shaxsiy/sayt; do
git init -q ~/$r
echo "# $r" > ~/$r/README.md
git -C ~/$r add README.md
git -C ~/$r commit -q -m "docs: README"
echo "$r -> $(git -C ~/$r oxirgi)"
done
git -C ~/ish/api config get --show-scope user.email
cd .. && rm -rf sozlama-sinovBiz ishga tushirdik:
ish/api -> 1c831bb aziz@kompaniya.example.com: docs: README
shaxsiy/sayt -> d96eb69 aziz@example.com: docs: README
global aziz@kompaniya.example.comIkki repo — ikki email, bitta global fayl. GIT_CONFIG_GLOBAL ni ham qaratdik: aks holda ba'zi tizimlarda Git HOME dan boshqa joydagi faylni o'qishi mumkin. Haqiqiy kompyuteringizda export HOME=… qilmaysiz — ~ o'z uy papkangiz bo'ladi.
12. Real ishda
- Qayerda uchraydi: tajribali dasturchilarning
~/.gitconfigfayli ko'pincha GitHub'dagi "dotfiles" repo'sida turadi va yangi kompyuterga bir buyruq bilan ko'chiriladi. Kompaniyaga kirganda birinchi kuniincludeIfbilan ish emailini ajratish — yaxshi odat. - Katta repolar: monorepo ishlatadigan kompaniyalarda
core.fsmonitor,git maintenanceva sparse-checkout (Katta repolar) birga yoqiladi. Microsoft o'z katta repolari uchun Scalar degan vositani yaratgan va u Git tarkibiga kirgan — Git hujjatiga ko'rascalar clonesparse-checkout va fon xizmatini birdaniga yoqadi (biz sinamadik). - Intervyu savollari: "Ish va shaxsiy loyihalarda turli email'ni qanday ajratasiz?", "
git rererenima?", "git statuskatta repoda sekin — nima qilasiz?"
Xulosa
- Sozlama uch darajada;
git config get --show-scopeva--show-originqiymat qayerdan kelganini ko'rsatadi, oxirgi o'qilgani yutadi. - Alias — qisqa buyruq;
!li alias — shell skript, begonasini o'qimasdan qo'shmang. includeIf "gitdir/i:~/ish/"vahasconfig:remote.*.url:— ish emailini avtomatik qo'yadi; oxirgi/va harf farqi jim xato beradi.push.autoSetupRemote,fetch.prune,zdiff3,rerere,histogram— kundalik ishni tezlashtiradi va aniqlashtiradi;autocorrect immediate— xavfli.- Katta repoda
untrackedCache,fsmonitor,git maintenance— lekin avval o'lchang: kanonda 95 → 83 ms, commit-graph 2 000 commitda foyda bermadi.
Keyingi dars: Jamoadagi yangi loyihaga kirish — notanish kod bazasida birinchi hafta: arxitektura xaritasi, git log bilan tarixni o'qish va birinchi kichik vazifa.
Manbalar
- Git hujjati — git-config (
includeIf,help.autoCorrect,merge.conflictStyle,feature.manyFiles): https://git-scm.com/docs/git-config - Git hujjati — git-rerere: https://git-scm.com/docs/git-rerere
- Git hujjati — git-maintenance (
loose-objectsvazifasi,start): https://git-scm.com/docs/git-maintenance - Git hujjati — git-fsmonitor--daemon: https://git-scm.com/docs/git-fsmonitor--daemon
- Git hujjati — scalar: https://git-scm.com/docs/scalar (sinalmagan, 2026-11)
- GitLens (VS Code Marketplace): https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens (sinalmagan, 2026-11)
- Kanon tajribasi (IlmHamroh, 2026-11-04): Git 2.54.0.windows.1; 40 001 faylli sun'iy repo —
git status, commit-graph vagit maintenanceo'lchovlari. Alias,includeIf(gitdir,gitdir/i,hasconfig),push.autoSetupRemote,fetch.prune,help.autocorrect,zdiff3,rerere,histogram,loose-objectsikki yugurishi va mashq yechimlari — biz ishga tushirdik (2026-11-04).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!