ОНОЛ 05

Хувилбарын Удирдлага (Git)

ЛЕКЦ 05: ХУВИЛБАРЫН УДИРДЛАГА БА GIT (Version Control & Git)

Хичээлийн зорилго: Хувилбарын удирдлагын суурь ойлголт, Git-ийн ажиллагааны зарчим, branch стратеги, багаар хамтран ажиллах workflow, CI/CD-ийн үндэс зэргийг эзэмшүүлэх.

Хамрах хүрээ: VCS тодорхойлолт, Git архитектур, суурь командууд, branching стратеги, merge vs rebase, pull request, conflict шийдвэрлэх, CI/CD-ийн үндэс.



ХЭСЭГ 1: ОНОЛЫН СУУРЬ (Theory & Foundations)

1.1 Хувилбарын удирдлага (Version Control) гэж юу вэ?

Version Control System (VCS) гэдэг нь файлуудын өөрчлөлтийг цаг хугацааны туршид бүртгэж, хадгалж, удирдах систем.

🔑 Тодорхойлолт: VCS нь кодын бүх өөрчлөлтийн түүхийг хадгалж, хэн, хэзээ, юу өөрчилсөн гэдгийг бүртгэдэг.

Зүйрлэл:

💡 Google Docs дээр баримт бичих — бүх өөрчлөлтийн түүхийг харж, хуучин хувилбар руу буцаж болдог шиг, VCS нь кодын "цаг хугацааны машин".

VCS-ийн шийддэг асуудлууд:

#АсуудалVCS-гүйVCS-тэй
1Файл алдахСанамсаргүй устгавал сэргээх боломжгүйБүх түүх хадгалагдсан, сэргээж болно
2Хэн юу өөрчилсөн?Мэдэхгүйgit log, git blame
3Хамтран ажиллахФайл дарж бичихBranch, merge, pull request
4Хуучин хувилбарproject_v1, project_v2_final_FINALCommit бүр нь хувилбар
5Туршилт хийхЭх кодыг эвдэх эрсдэлBranch дээр туршиж, merge хийх

VCS-гүй хөгжүүлэгчийн амьдрал:

📁 project_v1/
📁 project_v2/
📁 project_v2_final/
📁 project_v2_final_REAL/
📁 project_v2_final_REAL_THIS_ONE/
📁 project_backup_20240115/
📁 project_DO_NOT_DELETE/

😅 Танил санагдаж байна уу? VCS энэ бүх асуудлыг шийднэ.


1.2 VCS-ийн төрлүүд

1.2.1 Локал VCS (Local VCS)

Файлын өөрчлөлтийг зөвхөн нэг компьютер дээр хадгална.

[Ажлын хавтас] → [Локал мэдээллийн сан]
  • Жишээ: RCS (Revision Control System)
  • Сул тал: Хамтран ажиллах боломжгүй, компьютер эвдэрвэл бүгд алдагдана

1.2.2 Төвлөрсөн VCS (Centralized VCS — CVCS)

Нэг төв сервер дээр бүх түүх хадгалагдана. Хөгжүүлэгчид серверээс файл татаж ажиллана.

[Хөгжүүлэгч A] ←→ [ТӨВ СЕРВЕР] ←→ [Хөгжүүлэгч B]
  • Жишээ: SVN (Subversion), CVS, Perforce
  • Давуу тал: Хамтран ажиллах боломжтой, нэг газар удирдах
  • Сул тал: Сервер унтарвал хэн ч ажиллаж чадахгүй, сервер эвдэрвэл бүх түүх алдагдана

1.2.3 Тархсан VCS (Distributed VCS — DVCS)

Хөгжүүлэгч бүр бүтэн хуулбар (clone) авна — бүх түүхтэй.

[Хөгжүүлэгч A: Бүтэн хуулбар] ←→ [Алсын сервер] ←→ [Хөгжүүлэгч B: Бүтэн хуулбар]
  • Жишээ: Git, Mercurial
  • Давуу тал: Офлайн ажиллах боломжтой, сервер эвдэрсэн ч локал хуулбар бүрэн, маш хурдан
  • Git нь DVCS-ийн хамгийн түгээмэл, стандарт хэрэгсэл

💡 Зүйрлэл: CVCS = Номын сангаас ном зээлэх (нэг л хуулбар). DVCS = Ном бүрийг хуулж авах (хүн бүрт бүтэн хуулбар).


1.3 Git-ийн түүх ба философи

Түүх:

  • 2005 он: Linus Torvalds (Linux-ийн зохиогч) Git-ийг бүтээсэн
  • Шалтгаан: Linux цөмийн хөгжүүлэлтэд ашигладаг байсан BitKeeper хэрэгсэлтэй маргалдсан
  • Linus-ийн зорилго: Хурдан, энгийн, тархсан, том төслийг удирдах чадвартай

Git-ийн философи:

ЗарчимТайлбар
ХурдБараг бүх үйлдэл локал → маш хурдан
Энгийн дизайнЦөөн суурь ойлголт дээр суурилсан
Шугаман бус хөгжүүлэлтОлон мянган зэрэгцээ branch дэмжинэ
Бүрэн тархсанХөгжүүлэгч бүр бүтэн түүхтэй
Том төсөлLinux цөм (25+ сая мөр код) удирдах чадвартай

1.4 Git-ийн архитектур — Гурван бүс (Three Areas)

Git нь 3 үндсэн бүстэй:

┌─────────────┐    git add    ┌──────────────┐   git commit   ┌──────────────┐
│  WORKING     │ ──────────→  │   STAGING     │ ────────────→  │  REPOSITORY  │
│  DIRECTORY   │              │   AREA        │                │  (.git)      │
│  (Ажлын     │ ←────────── │   (Index)     │                │  (Түүх)     │
│   хавтас)   │  файл засах  │   (Бэлтгэл)  │                │              │
└─────────────┘              └──────────────┘                └──────────────┘

Гурван бүсийн тайлбар:

БүсАнглиТайлбар
Ажлын хавтасWorking DirectoryФайлуудаа засварладаг газар. Кодоо бичдэг
Бэлтгэл бүсStaging Area (Index)Дараагийн commit-д оруулах файлуудыг бэлтгэх "тайз"
РепозиторRepository (.git)Бүх commit-ийн түүх хадгалагддаг

💡 Зүйрлэл: Гэрийн хоол хийх:

  • Working Directory = Гал тогоо (хоол бэлтгэх)
  • Staging Area = Тавлага (бэлэн болсон хоолыг тавих)
  • Repository = Хоолны зураг авах (түүх хадгалах)

1.5 Git-ийн суурь командууд

1.5.1 Репозитор үүсгэх / клонлох

# Шинэ репозитор үүсгэх
git init

# Одоо байгаа репозиторыг клонлох (хуулах)
git clone https://github.com/user/repo.git

1.5.2 Өөрчлөлт хийх цикл

# 1. Файлуудын төлөвийг шалгах
git status

# 2. Файлыг staging area-д нэмэх
git add filename.java           # Нэг файл
git add .                       # Бүх өөрчлөлт

# 3. Commit хийх (түүхэнд хадгалах)
git commit -m "Оюутны бүртгэлийн модуль нэмсэн"

# 4. Алсын сервер рүү илгээх
git push origin main

1.5.3 Түүх харах

# Commit-ийн түүх харах
git log
git log --oneline              # Товч хэлбэрээр
git log --oneline --graph      # График хэлбэрээр

# Хэн ямар мөр бичсэнийг харах
git blame filename.java

# Хоёр commit-ийн ялгааг харах
git diff commit1 commit2

1.5.4 Буцаах (Undo)

# Staging area-аас буцаах (unstage)
git restore --staged filename.java

# Ажлын хавтас дахь өөрчлөлтийг цуцлах
git restore filename.java

# Сүүлийн commit-ийн мессежийг засах
git commit --amend -m "Шинэ мессеж"

# Commit-ийг буцаах (шинэ commit үүсгэж)
git revert HEAD

1.6 Branching (Салаалт)

Branch гэж юу вэ?

Branch нь хөгжүүлэлтийн тусдаа шугам. Үндсэн кодонд нөлөөлөхгүйгээр шинэ функц, алдаа засвар зэргийг хийх боломж олгоно.

💡 Зүйрлэл: Номын зэрэгцээ бүлгүүд шиг — нэг бүлгийг бичиж байхдаа нөгөө бүлгийг эвдэхгүй. Дууссаны дараа нэгтгэнэ.

          feature/login
         ┌──●──●──●──┐
        ╱              ╲ merge
main ──●──●──────────────●──●──
              ╲              ╱
               └──●──●──●──┘
              feature/payment

Суурь branch командууд:

# Бүх branch жагсаалт
git branch

# Шинэ branch үүсгэх
git branch feature/login

# Branch руу шилжих
git checkout feature/login
# эсвэл (шинэ арга)
git switch feature/login

# Үүсгэж шилжих (нэг алхам)
git checkout -b feature/payment
# эсвэл
git switch -c feature/payment

# Branch устгах
git branch -d feature/login

1.7 Merge ба Rebase

1.7.1 Merge (Нэгтгэх)

Хоёр branch-ийн түүхийг нэгтгэж, шинэ merge commit үүсгэнэ.

# main branch руу шилжих
git checkout main

# feature branch-ийг нэгтгэх
git merge feature/login
          feature/login
         ┌──●──●──●──┐
        ╱              ╲ merge commit
main ──●──●──────────────●──

Давуу тал: Түүх бүрэн хадгалагдана, хэзээ merge хийсэн тодорхой Сул тал: Олон merge commit → Түүх нарийн болж болно

1.7.2 Rebase (Суурь шилжүүлэх)

Feature branch-ийн commit-уудыг main-ийн ОРОЙД дахин тавина.

# feature branch дээр байхдаа
git checkout feature/login
git rebase main
ӨМНӨ:                          ДАРАА:
main: ──●──●──●                main: ──●──●──●
             ╲                                 ╲
feature:      ●──●              feature:        ●'──●'

Давуу тал: Цэвэр, шугаман түүх Сул тал: Түүхийг дахин бичдэг → Хуваалцсан branch дээр ХЭЗЭЭ Ч ХЭРЭГЛЭХГҮЙ

Merge vs Rebase хэзээ ашиглах:

НөхцөлMergeRebase
Нийтийн branch (main)
Хувийн feature branch
Түүх хадгалах чухал
Цэвэр түүх хэрэгтэй
Алтан дүрэмАюулгүйНийтийн branch-д хэзээ ч rebase хийхгүй

1.8 Merge Conflict (Зөрчил)

Conflict хэзээ үүсдэг вэ?

Хоёр branch дээр ижил файлын ижил мөрийг өөр өөрөөр засварласан → Git автоматаар нэгтгэж чадахгүй.

Хөгжүүлэгч A:  greeting = "Сайн байна уу";
Хөгжүүлэгч B:  greeting = "Сайн уу";
                ↓
            CONFLICT!

Conflict шийдвэрлэх:

// Git-ийн харуулдаг хэлбэр:
<<<<<<< HEAD
    greeting = "Сайн байна уу";     // Одоогийн branch
=======
    greeting = "Сайн уу";           // Нэгтгэж буй branch
>>>>>>> feature/greeting

// Хөгжүүлэгч шийднэ:
    greeting = "Сайн байна уу!";    // Зөв хувилбарыг сонгоно

Шийдвэрлэх алхам:

# 1. Conflict-той файлуудыг олох
git status

# 2. Файлуудыг нээж, conflict-ийг гараар засах
# <<<<<<< , ======= , >>>>>>> тэмдэглэгээг устгах

# 3. Засварласан файлуудыг staging-д нэмэх
git add filename.java

# 4. Merge commit хийх
git commit -m "Merge conflict шийдвэрлэсэн"

💡 Зөвлөгөө: IDE-үүд (IntelliJ, VS Code) conflict шийдвэрлэхэд визуал хэрэгсэл санал болгодог — харьцуулж, сонгоход хялбар.


1.9 Branching стратеги

1.9.1 Git Flow

Хамгийн алдартай, томоохон төслүүдэд тохиромжтой.

main ─────────────────────────────────────── (production)
  ╲                                      ╱
   develop ──────────────────────────────── (хөгжүүлэлт)
      ╲          ╲               ╱
       feature/A  feature/B ────┘
                  ╲
                   release/1.0 ──── (бэлтгэл)
                   ╲
                    hotfix/bug ──── (яаралтай засвар)
BranchЗорилго
mainProduction код — үргэлж ажилладаг
developХөгжүүлэлтийн үндсэн branch
feature/Шинэ функц бүрд тусдаа branch
release/Шинэ хувилбар гаргахын өмнөх бэлтгэл
hotfix/Production-д гарсан яаралтай алдааны засвар

1.9.2 GitHub Flow

Энгийн, жижиг багуудад тохиромжтой.

main ──●──●──●──●──●──●──●──●──●──
        ╲     ╱   ╲        ╱
         ●──●      ●──●──●
      feature    feature
      + PR       + PR

Дүрмүүд:

  1. main branch үргэлж deploy хийж болохуйц
  2. Шинэ ажил бүрд main-аас branch салгах
  3. Тогтмол commit хийж, push хийх
  4. Pull Request нээх
  5. Code Review-ийн дараа merge хийх
  6. Merge хийсний дараа deploy

1.9.3 Trunk-Based Development

Хамгийн энгийн, CI/CD-д тохиромжтой.

main (trunk) ──●──●──●──●──●──●──●──●──●──
                ╲╱  ╲╱        ╲╱
            маш богино feature branch-ууд

Зарчим: Бүх хөгжүүлэгч main руу шууд (эсвэл маш богино branch-аар) commit хийнэ.


1.10 Pull Request (PR) / Merge Request (MR)

Pull Request гэж юу вэ?

Pull Request нь кодыг нэгтгэхийн ӨМНӨ багийн гишүүдээр шалгуулах хүсэлт.

💡 Зүйрлэл: Илтгэлийг хэвлэхийн өмнө багшаар шалгуулах шиг — PR нь кодыг merge хийхийн өмнө шалгуулах.

PR-ийн давуу тал:

#Давуу талТайлбар
1Code ReviewБусад хөгжүүлэгч кодыг шалгана
2ЧанарАлдаа, code smell-ийг merge-ийн өмнө олно
3Мэдлэг хуваалцахБаг бүгд кодыг мэддэг
4Автомат шалгалтCI/CD тест автоматаар ажиллана
5БаримтжуулалтЯагаад энэ өөрчлөлт хийсэн бэ гэдэг нь бүртгэгдэнэ

Сайн PR-ийн шинж:

ШинжТайлбар
Жижиг200-400 мөр өөрчлөлт (дээд тал нь)
Нэг зорилготойНэг PR = Нэг функц эсвэл нэг алдаа засвар
ТайлбартайЮу хийсэн, яагаад хийсэн, хэрхэн тестлэсэн
Тест бүхийШинэ код + тест хамт

1.11 Commit мессежийн стандарт

Сайн commit мессеж бичих:

<төрөл>(<хамрах хүрээ>): <товч тайлбар>

<дэлгэрэнгүй тайлбар (заавал биш)>

<холбоос, жишээ нь issue дугаар>

Conventional Commits стандарт:

ТөрөлТайлбарЖишээ
featШинэ функцfeat(auth): нэвтрэлтийн модуль нэмсэн
fixАлдаа засварfix(cart): сагсны тооцоолол засав
refactorКод бүтцийн засварrefactor(user): UserService-ийг хуваасан
testТест нэмэх/засахtest(order): захиалгын unit тест нэмсэн
docsБаримт бичигdocs(readme): суулгах заавар нэмсэн
styleФормат өөрчлөлтstyle: хоосон мөрүүд цэвэрлэсэн
choreБусад засварchore: dependency шинэчлэсэн

Муу vs Сайн commit мессеж:

# ❌ БУРУУ:
git commit -m "fix"
git commit -m "update"
git commit -m "asdf"
git commit -m "done"

# ✅ ЗӨӨВ:
git commit -m "feat(student): оюутны GPA тооцоолох функц нэмсэн"
git commit -m "fix(login): нууц үг буруу үед алдааны мессеж засав"
git commit -m "refactor(order): calculateTotal() методыг хуваасан"

1.12 .gitignore

.gitignore гэж юу вэ?

Git-д бүртгэхгүй файлуудын жагсаалт. Компайл хийсэн файл, IDE тохиргоо, нууц мэдээлэл зэргийг Git-д нэмэхгүй.

Java төслийн .gitignore жишээ:

# Compiled files
*.class
*.jar
*.war

# Build directories
/target/
/build/
/out/

# IDE files
.idea/
*.iml
.vscode/
.eclipse/

# OS files
.DS_Store
Thumbs.db

# Environment / Secrets
.env
*.properties
!application-example.properties

# Logs
*.log

# Dependencies
/node_modules/

⚠️ Чухал: API key, нууц үг, токен зэрэг нууц мэдээллийг ХЭЗЭЭ Ч Git-д нэмж болохгүй! .env файлд хадгалж, .gitignore-д нэмэх.


1.13 CI/CD-ийн үндэс

CI (Continuous Integration) — Тасралтгүй нэгтгэл

Хөгжүүлэгчид код push хийх бүрд автоматаар build, тест ажиллуулах.

Хөгжүүлэгч → git push → CI сервер → Build → Test → Үр дүн мэдэгдэх
                                        ↓
                                   ✅ Pass → Merge зөвшөөрөх
                                   ❌ Fail → Хөгжүүлэгчид мэдэгдэх

CD (Continuous Delivery / Deployment) — Тасралтгүй хүргэлт

CI-ийн дараа автоматаар staging/production орчинд deploy хийх.

Code → Build → Test → Staging → Production
         ↑ CI ↑        ↑ CD ↑

CI/CD-ийн давуу тал:

#Давуу талТайлбар
1Алдааг эрт олохPush бүрт тест ажиллана
2Хурдан хүргэлтАвтомат deploy → Хүргэлт хурдасна
3ИтгэлцэлТест pass = Код найдвартай
4Давталт багаснаГараар build, test, deploy хийхгүй

CI/CD хэрэгслүүд:

ХэрэгсэлТайлбар
GitHub ActionsGitHub-тай нэгдсэн, үнэгүй
GitLab CI/CDGitLab-тай нэгдсэн
JenkinsНээлттэй эхийн, уян хатан
CircleCICloud-based CI/CD
Travis CIНээлттэй эхийн төслүүдэд

GitHub Actions жишээ:

# .github/workflows/ci.yml
name: Java CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'
    - name: Build with Maven
      run: mvn clean verify
    - name: Run tests
      run: mvn test

1.14 Git хамтын ажиллагааны зөвлөмжүүд

#ЗөвлөмжТайлбар
1Тогтмол commit хийхЖижиг, тогтмол commit > Том, ховор commit
2Утга учиртай мессеж бичих"fix" биш → "fix(auth): token хугацаа дуусах алдааг засав"
3Branch ашиглахmain дээр шууд ажиллахгүй
4Pull Request ашиглахCode review-гүйгээр merge хийхгүй
5Conflict-ийг түргэн шийдэхУдаан орхивол conflict ихсэнэ
6Push-ийн өмнө pull хийхgit pull --rebase origin main
7Нууц мэдээлэл Git-д нэмэхгүй.env, API key → .gitignore
8.gitignore зөв тохируулахBuild файл, IDE тохиргоо нэмэхгүй


ХЭСЭГ 2: ТҮЛХҮҮР ҮГ БА МЭРГЭЖЛИЙН НЭР ТОМЬЁО (Keywords & Glossary)

#Англи нэр томьёоМонгол утгаДэлгэрэнгүй тайлбар
1Version Control System (VCS)Хувилбарын удирдлагын системФайлуудын өөрчлөлтийн түүхийг бүртгэж, удирдах систем.
2Repository (Repo)Репозитор / АгуулахКодын бүх файл, түүхийг хадгалдаг агуулах.
3CommitКоммит / БүртгэлӨөрчлөлтийг түүхэнд хадгалах үйлдэл. Нэг "хадгалах цэг".
4BranchСалаалт / СалбарХөгжүүлэлтийн тусдаа шугам. Үндсэн кодонд нөлөөлөхгүй.
5MergeНэгтгэхХоёр branch-ийн өөрчлөлтийг нэг болгох.
6RebaseСуурь шилжүүлэхBranch-ийн commit-уудыг өөр branch-ийн оройд тавих.
7CloneКлонлох / ХуулахАлсын репозиторын бүтэн хуулбар авах.
8PushТүлхэх / ИлгээхЛокал commit-уудыг алсын сервер рүү илгээх.
9PullТатахАлсын серверээс шинэ өөрчлөлтийг татах.
10FetchТатах (нэгтгэхгүй)Алсын серверээс мэдээлэл татах, гэхдээ автоматаар merge хийхгүй.
11Staging Area (Index)Бэлтгэл бүсДараагийн commit-д оруулах файлуудыг бэлтгэх газар.
12Working DirectoryАжлын хавтасФайлуудаа засварладаг газар.
13HEADТэргүүлэгчОдоогийн branch-ийн хамгийн сүүлийн commit руу заадаг заагч.
14RemoteАлсын серверАлсад байрлах репозитор (GitHub, GitLab гэх мэт).
15OriginЭх үүсвэрКлонлосон алсын серверийн анхдагч нэр.
16Pull Request (PR)Татах хүсэлтКодыг merge хийхийн өмнө шалгуулах хүсэлт (GitHub).
17Merge Request (MR)Нэгтгэх хүсэлтPR-тэй ижил, GitLab дахь нэр.
18Merge ConflictНэгтгэлийн зөрчилХоёр branch ижил мөрийг өөрөөр засварласан → автомат нэгтгэх боломжгүй.
19Git FlowГит урсгалmain, develop, feature, release, hotfix branch бүхий стратеги.
20GitHub FlowГитХаб урсгалЭнгийн стратеги: main + feature branch + PR.
21Trunk-Based DevelopmentҮндсэн мөчирт суурилсанБүгд main руу богино branch-аар commit хийх стратеги.
22CI (Continuous Integration)Тасралтгүй нэгтгэлPush бүрт автоматаар build, тест ажиллуулах.
23CD (Continuous Delivery)Тасралтгүй хүргэлтCI-ийн дараа автоматаар deploy хийх.
24TagШошгоТодорхой commit-д нэр өгөх. Хувилбар гаргахад (v1.0.0).
25StashНөөцлөх / Түр хадгалахДуусаагүй өөрчлөлтийг түр хадгалж, цэвэр branch руу шилжих.
26Cherry-pickСонгон авахТодорхой commit-ийг өөр branch руу хуулах.
27.gitignoreГит үл тоомсорлохGit-д бүртгэхгүй файлуудын жагсаалт.
28BlameБуруутгах / Гэм бурууФайлын мөр бүрийг хэн бичсэнийг харуулах.
29DiffЯлгааХоёр commit/файлын хоорондох ялгааг харуулах.
30RevertБуцаахCommit-ийг буцааж, шинэ commit үүсгэх (түүх хадгалагдана).
31ResetДахин тохируулахHEAD-ийг өмнөх commit руу шилжүүлэх (түүх өөрчлөгдөж болно).
32AmendЗасахСүүлийн commit-ийн мессеж/агуулгыг засах.
33ForkСалаалуулахБусдын репозиторыг өөрийн бүртгэлд хуулах (GitHub).
34Code ReviewКодын шалгалтБусад хөгжүүлэгч кодыг шалгаж, санал болгох.
35Conventional CommitsСтандарт коммитfeat:, fix:, refactor: гэх мэт commit мессежийн стандарт.
36Distributed VCSТархсан VCSХөгжүүлэгч бүр бүтэн хуулбар авдаг (Git, Mercurial).
37Centralized VCSТөвлөрсөн VCSНэг төв серверт бүх түүх хадгалагддаг (SVN).
38GitHub ActionsГитХаб ҮйлдлүүдGitHub-ийн CI/CD автоматжуулалтын хэрэгсэл.
39HotfixЯаралтай засварProduction-д гарсан алдааг яаралтай засах branch.
40Semantic VersioningУтга бүхий хувилбарлалтMAJOR.MINOR.PATCH (v1.2.3) хувилбарын дүрэм.