Git / git rebase

git rebase

git rebase нь branch-ийн commit-уудыг өөр байрлалаас дахин "тавих" үйлдэл. Merge-ийн нэг өөр хувилбар боловч commit түүхийг шулуун, цэвэр байлгадаг онцлогтой.

Rebase vs Merge ялгаа

Merge — хоёр branch-ийн түүхийг нэгтгэж, merge commit үүсгэдэг:

код
main:    A → B → E → M
                  ↗
feature:        C → D

Rebasefeature-ийн commit-уудыг main-ийн сүүлийн commit-ийн дараа дахин тавьдаг:

код
Өмнө:
main:    A → B → E
feature: A → B → C → D

Дараа (rebase):
main:    A → B → E
feature: A → B → E → C' → D'

C', D' нь C, D-тэй ижил өөрчлөлттэй ч шинэ hash-тай commit — тэд E-ийн дараа "дахин тавигдсан".

Rebase-ийн дараа fast-forward merge хийхэд түүх шулуун шугам болно:

код
main:    A → B → E → C' → D'

Merge commit байхгүй, цэвэр шулуун түүх.

git rebase хэрэглэх

feature branch дээр байхдаа main-ийн шинэчлэлтийг авах:

bash
git switch feature/login
git rebase main
код
Successfully rebased and updated refs/heads/feature/login.

Дараа нь main руу fast-forward merge хийнэ:

bash
git switch main
git merge feature/login

Rebase дахь conflict

Rebase хийхэд ч conflict гарч болно. Merge-ийн нэг л удаагийн оронд commit тус бүрд conflict гарч болох учир арай илүү анхааралтай байх хэрэгтэй.

Conflict засварласны дараа:

bash
git add засварласан-файл.ts
git rebase --continue

Rebase зогсоож, анхны байдалд буцах:

bash
git rebase --abort

Interactive rebase — git rebase -i

Interactive rebase нь commit-уудыг засварлах, нэгтгэх, дахин эрэмбэлэх хамгийн хүчирхэг хэрэгсэл. Сүүлийн N commit-ийг засварлах:

bash
git rebase -i HEAD~4

Editor нээгдэж commit-уудын жагсаалт харагдана:

код
pick 3f2a1bc feat: нэвтрэх форм нэмэх
pick a1b2c3d fix: товч ажиллахгүй байсан засах
pick 9f8e7d6 wip: дахин засах
pick 7c6b5a4 feat: Supabase холбох

# Commands:
# p, pick   = use commit
# r, reword = use commit, but edit the commit message
# e, edit   = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup  = like squash, but discard this commit's log message
# d, drop   = remove commit

squash — commit-уудыг нэгтгэх

"wip" гэх мэт завсрын commit-уудыг урьдах commit-тай нэгтгэх:

код
pick 3f2a1bc feat: нэвтрэх форм нэмэх
squash a1b2c3d fix: товч ажиллахгүй байсан засах
squash 9f8e7d6 wip: дахин засах
pick 7c6b5a4 feat: Supabase холбох

Editor хадгалж гарахад дараагийн editor нээгдэж нэгтгэсэн commit-ийн мессеж оруулахыг хүснэ.

fixup — мессежгүй нэгтгэх

squash-тай адил ч нэгтгэгдэх commit-ийн мессежийг автоматаар хаядаг:

код
pick 3f2a1bc feat: нэвтрэх форм нэмэх
fixup a1b2c3d fix: товч ажиллахгүй байсан засах
fixup 9f8e7d6 wip: дахин засах

Үр дүн: "feat: нэвтрэх форм нэмэх" нэртэй нэг commit, завсрын мессежүүд алга болно.

reword — мессеж засах

код
reword 7c6b5a4 feat: Supabase холбох

Editor нээгдэж зөвхөн тэр commit-ийн мессежийг засварлуулна.

Golden rule of rebasing — Rebase-ийн алтан дүрэм

Нийтэд хуваалцсан (push хийсэн) branch дээр rebase хийж болохгүй.

Rebase нь commit-уудыг шинэ hash-тай дахин үүсгэдэг. Хэрэв тэр commit-уудыг бусад хүн аль хэдийн татаж авсан бол тэдний repository-тэй зөрчилдөх болно — түүх хооронд нийцэхгүй болно.

Аюулгүй: Зөвхөн өөрийн локал, push хийгдээгүй commit-уудад rebase ашиглах.

Аюулгүй хэрэглээ:

bash
# main-ийн шинэчлэлтийг feature branch-д авах (push хийгдээгүй байх ёстой)
git switch feature/миний-боломж
git rebase main

Аюултай хэрэглээ:

bash
# Бусад хүн pull хийсэн main branch дээр rebase — БОЛОХГҮЙ
git switch main
git rebase feature/login   # ← Аюулгүй биш

Дараагийн хичээлд:

git stash ашиглан дуусаагүй ажлыг түр хажуу тийш хадгалах аргыг судална.