Bare Repository — server uchun repository
Muammodan boshlaylik
GitHub ishlatib bo'lmaydigan holat: kompaniya siyosati kodni tashqi xizmatlarda saqlashni taqiqlaydi, yoki internetsiz ichki tarmoq. Ofisda Linux server bor. Unda "o'z GitHub ingizni" qanday qilasiz?
Birinchi urinish — serverda oddiy repozitoriy:
# serverda
git init /srv/git/dokon
# kompyuteringizda
git push server main
remote: error: refusing to update checked out branch: refs/heads/main
remote: error: By default, updating the current branch in a non-bare repository
remote: is denied, because it will make the index and work tree inconsistent
Git rad etdi. Sabab — serverdagi repozitoriyda ishchi papka bor. Server uchun kerak — bare repository.
Bare repository nima?
Bare ("yalang'och") repozitoriy — ishchi papkasiz repozitoriy: faqat .git ichidagi narsa.
Oddiy repozitoriy: Bare repozitoriy:
dokon/ dokon.git/
├── .git/ ├── HEAD
│ ├── HEAD ├── config
│ ├── objects/ ├── objects/
│ └── refs/ ├── refs/
├── index.html ← ishchi papka └── hooks/
└── src/
| Oddiy | Bare | |
|---|---|---|
| Ishchi papka (fayllar) | ✅ | ❌ |
| Unda commit qilish, fayllarni tahrirlash | ✅ | ❌ |
| Unga push qilish | ⚠️ Joriy branch ga — rad etiladi | ✅ Asosiy maqsadi |
| Nomlash an'anasi | dokon/ |
dokon.git |
| Qayerda | Dasturchining kompyuteri | Server — markaziy nuqta |
Nima uchun oddiy repozitoriyga push qilib bo'lmaydi?
Serverda kimdir main ochiq turgan ishchi papkada ishlayapti deb tasavvur qiling. Siz main ga push qilasiz — branch ko'rsatkichi siljiydi, lekin uning ishchi papkasidagi fayllar va staging — eski holatda. Uning keyingi git status i aqldan ozgandek ko'rinadi. Git buni oldini oladi. Bare repozitoriyda ishchi papka yo'q — ziddiyat ham yo'q.
[!INFO] GitHub, GitLab va boshqa barcha Git serverlari ichida aynan bare repozitoriylar saqlaydi. GitHub dagi
otabek/dokon— serverdagidokon.gitbare repozitoriysi va uning ustidagi veb-interfeys.
Bare repozitoriy yaratish
git init --bare /srv/git/dokon.git
Yoki mavjud loyihadan:
git clone --bare dokon dokon.git
Oddiy Git server — SSH orqali
Alohida dastur kerak emas — SSH va Git yetarli (Linux kursi, 34, 42-darslar).
Serverda
sudo adduser --disabled-password git
sudo -u git mkdir -p /home/git/.ssh
# dasturchilarning ochiq kalitlarini qo'shish:
cat otabek.pub malika.pub | sudo -u git tee -a /home/git/.ssh/authorized_keys
sudo -u git chmod 600 /home/git/.ssh/authorized_keys
sudo -u git git init --bare /home/git/dokon.git
Xavfsizlik uchun git foydalanuvchisiga shell o'rniga cheklangan git-shell bering — u faqat Git buyruqlarini bajara oladi:
sudo chsh -s "$(which git-shell)" git
Dasturchilar kompyuterida
git remote add origin git@server.local:dokon.git
git push -u origin main
# boshqa dasturchi:
git clone git@server.local:dokon.git
Shu bilan — ishlaydigan markaziy Git server. Pull Request, Issues, veb-interfeys yo'q — lekin push, pull, clone, branch lar — hammasi ishlaydi.
post-receive hook bilan deploy
Bare repozitoriyda server tomonidagi hook lar (47-dars) ishlaydi. Klassik oddiy deploy: push → sayt yangilanadi.
# serverda: /home/git/dokon.git/hooks/post-receive
#!/bin/bash
TARGET=/var/www/dokon
while read oldrev newrev ref; do
if [ "$ref" = "refs/heads/main" ]; then
echo "🚀 main yangilandi — deploy..."
git --work-tree="$TARGET" --git-dir="/home/git/dokon.git" checkout -f main
echo "✅ Deploy tugadi"
fi
done
chmod +x /home/git/dokon.git/hooks/post-receive
git push origin main
remote: 🚀 main yangilandi — deploy...
remote: ✅ Deploy tugadi
--work-tree — bare repozitoriyning fayllarini boshqa papkaga "chiqarish". Statik saytlar uchun oddiy va samarali; murakkabroq ilovalar uchun — CI/CD (39-dars).
Bare repozitoriyning boshqa qo'llanishi
Zaxira nusxa — mirror
git clone --mirror git@github.com:otabek/dokon.git
cd dokon.git
git remote update # cron bilan muntazam yangilash
--mirror — bare + barcha ref lar (branch lar, teglar, notes) aniq nusxada. GitHub ishlamay qolsa yoki hisob bloklansa — butun tarix sizda. Boshqa joyga ko'chirish: git push --mirror git@gitlab.com:otabek/dokon.git.
Dotfiles
Uy papkadagi sozlama fayllarini (.bashrc, .gitconfig) to'g'ridan-to'g'ri Git da saqlashning mashhur usuli:
git init --bare ~/.dotfiles
alias dot='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
dot config status.showUntrackedFiles no
dot add ~/.bashrc ~/.gitconfig
dot commit -m "Dotfiles"
Uy papkangiz — ishchi papka, repozitoriy esa alohida; ~ da .git papkasi yo'q (5-darsdagi ogohlantirish).
To'liq o'z serveringiz
Veb-interfeys, PR, issue lar kerak bo'lsa — o'zingizning serveringizga o'rnatiladigan platformalar (Docker bilan bir necha daqiqada):
| Platforma | Xususiyati |
|---|---|
| Gitea / Forgejo | Yengil (bir necha yuz MB RAM), GitHub ga o'xshash interfeys |
| GitLab CE | To'liq: CI/CD, registri, issue lar — lekin og'ir (4+ GB RAM) |
Ular ham ichida — bare repozitoriylar.
Nima uchun shunday?
Nima uchun Git ishchi papkani va repozitoriyni ajratadi — ular doim birga emasmi?
Git dizaynida ular boshidan ikki alohida tushuncha edi: repozitoriy — tarix va obyektlar ma'lumotlar bazasi (.git), ishchi papka — shu bazadagi bitta versiyaning "ochilgan" ko'rinishi (6-dars). Dasturchiga ikkalasi kerak — u fayllarni tahrirlaydi. Serverga esa faqat birinchisi kerak — u faqat commitlarni qabul qiladi va beradi. Bu ajratish Git ga moslashuvchanlik beradi: bitta repozitoriyga bir nechta ishchi papka (worktree, 46-dars), ishchi papkasiz repozitoriy (bare), yoki boshqa joydagi ishchi papka (--work-tree, dotfiles). GitHub ning butun arxitekturasi aynan shu oddiy g'oya ustiga qurilgan.
Xulosa
Eslab qoling:
- Bare repozitoriy — ishchi papkasiz, faqat Git ma'lumotlari; nomi
nom.git git init --bareyokigit clone --bare- Push — bare repozitoriyga; oddiy repozitoriyning joriy branch iga — rad etiladi
- GitHub/GitLab ichida — bare repozitoriylar
- Oddiy Git server: SSH +
gitfoydalanuvchisi +git-shell+ bare repo post-receivehook +--work-tree— push bilan deploygit clone --mirror— to'liq zaxira- Veb-interfeys kerak bo'lsa — Gitea / Forgejo / GitLab
Keyingi bo'lim
9-bo'lim: Amaliy va Professional mavzular — SSH va GPG kalitlar, .gitattributes, Git LFS, GitHub CLI va GUI vositalar.