Birləşdirmək və ya merge etmək — Git-də iki qolun birləşdirilməsi əməliyyatıdır, dəyişiklikləri bir qoldan digərinə köçürür. Müasir proqramlaşdırmada merge feature qolunu layihənin əsas qoluna inteqrasiya etməyin standart üsuludur. GitHub Octoverse 2024 məlumatlarına görə, gündəlik 15 milyondan çox merge yerinə yetirilir. Merge — bir neçə proqramçının əməyini vahid məhsulda birləşdirməyə imkan verən əsas kollektiv iş mexanizmidir.
Əsas məqamlar
Git-də merge — iki və ya daha çox inkişaf tarixçəsini birinə birləşdirmə əməliyyatıdır. Proqramçı qolu birləşdirdikdə, Git avtomatik olaraq ümumi əcdadı (base commit) tapır və hər iki qoldan dəyişiklikləri özündə birləşdirən yeni merge commit yaradır. Three-way merge — üç vəziyyəti müqayisə edən standart alqoritm: ümumi əcdad, birinci qol və ikinci qol.
Merge prosesi git merge əmri ilə başlayır. Git qolların ayrılma nöqtəsini müəyyənləşdirir və dəyişiklikləri mənbə qoldan hədəf qola ardıcıl şəkildə tətbiq edir. Dəyişikliklər ziddiyyət təşkil etmirsə, Git parametrlərdən asılı olaraq fast-forward yerinə yetirir və ya merge commit yaradır. Fast-forward — hədəf qolun sadəcə mənbə qolun commit-lərinə irəlilədiyi ssenaridir.
# Hədəf qola keç və birləşdir
git checkout main
git merge feature/payment-module
# Açıq no-fast-forward ilə birləşdir
git merge --no-ff feature/payment-module
# Konfliktlər çox mürəkkəbdirsə, birləşməni ləğv et
git merge --abort
--no-ff (no fast-forward) flag-ı fast-forward mümkün olsa belə, məcburi olaraq merge commit yaradır. Bu, dəyişikliklərin ayrıca qolda edildiyi məlumatını saxlayır. Bir çox komandalar tarixçənin budaqlanmasını aşkar formada qorumaq üçün məhz bu yanaşmaya üstünlük verir.
Git-də qolların birləşdirilməsi üçün üç əsas strategiya mövcuddur, hər biri müəyyən ssenari üçün uyğundur. Strategiyanın seçimi komandanın mədəniyyətindən və layihə tarixçəsinin təmizliyinə olan tələblərdən asılıdır.
| Strategiya | Nəticə | Nə vaxt tətbiq etməli |
|---|---|---|
| Standard merge | merge commit + tam tarixçə | tam tarixçəyə dəyər verən komandalar |
| Squash merge | bir commit, tarixçə sıxışdırılıb | çoxlu kiçik commit-li feature qolları |
| Rebase merge | xətti tarixçə, merge commit olmadan | PR yaratmazdan əvvəl şəxsi feature qolları |
Standard merge iki valideyni olan merge commit yaradır. Tam tarixçə saxlanılır, lakin budaqlanma qrafı mürəkkəbləşir. Squash merge feature qolunun bütün commit-lərini birinə birləşdirir və onu hədəf qola tətbiq edir — tarixçə xətti və təmiz olur, lakin aralıq mərhələlər haqqında məlumat itir.
Rebase, tam hüquqlu merge olmasa da, eyni nəticəni əldə edir — bir qoldan dəyişikliklər digərinin üzərinə köçürülür. Fərq ondadır ki, tarixçə yenidən yazılır: feature qolunun commit-ləri hədəf qolun son commit-inin üzərində yenidən yaradılır. Bu, ideal xətti tarixçə verir, lakin göndərərkən force push tələb edir.
Merge zamanı konflikt iki qolda faylın eyni sətirləri dəyişdirildikdə yaranır. Git hansı variantı saxlayacağını avtomatik müəyyən edə bilmir və proqramçının müdaxiləsini tələb edir. Konfliktlər fayllarda xüsusi markerlər şəklində göstərilir: <<<<<<<, =======, >>>>>>>.
Konfliktin həlli prosesi bir neçə addımı əhatə edir. Əvvəlcə proqramçı konfliktli faylı açır və lazımi dəyişiklikləri əl ilə seçir. Sadəcə versiyalardan birini seçmək deyil, hər iki dəyişikliyin məntiqini anlamaq və düzgün qərar qəbul etmək vacibdir. Faylı redaktə etdikdən sonra konflikt markerləri silinir və dəyişikliklər git add vasitəsilə staging area-ya əlavə edilir.
# Konfliktli faylların siyahısına bax
git status
# Mergetool-u işə sal (məsələn, VS Code, IntelliJ)
git mergetool
# Bütün konfliktləri həll etdikdən sonra
git add .
git merge --continue
# Və ya birləşməni tamamilə ləğv et
git merge --abort
Vizual merge alətlərindən istifadə konfliktlərin həllini xeyli sürətləndirir. VS Code, IntelliJ IDEA və GitKraken üç panelli interfeys təqdim edir: cari qol, daxil olan qol və nəticə. Git mergetool aləti konfliktli hər bir fayl üçün konfiqurasiya edilmiş redaktoru avtomatik açır.
Mürəkkəb konfliktlərdən qaçmağın ən yaxşı yolu feature qolunun əsas qolla müntəzəm sinxronlaşdırılmasıdır. Proqramçı öz qolunu gündə bir dəfə main ilə birləşdirirsə, konfliktlər kiçik və asan həll olunan olacaq. Dəyişikliklərin bir həftə yığılması mürəkkəb konfliktlərə və yüksək səhv riskinə gətirib çıxarır.
Rebase və merge — dəyişiklikləri birləşdirməyin iki üsuludur və onlar arasında seçim komandalarda tez-tez mübahisələrə səbəb olur. Rebase commit-ləri bir qoldan digərinin üzərinə köçürərək tarixçəni yenidən yazır. Merge birləşmə tarixçəsini saxlayaraq yeni merge commit yaradır. Hər yanaşmanın öz üstünlükləri və məhdudiyyətləri var.
Rebase, proqramçı öz lokal feature qolunda işləyərkən və Pull Request yaratmazdan əvvəl təmiz xətti tarixçə əldə etmək istədikdə uyğundur. Rebase-dən sonra bütün commit-lər ardıcıl düzülür, lazımsız merge commit-lər olmur. Lakin rebase force push tələb edir və eyni vaxtda bir neçə nəfərin işlədiyi qollarda tətbiq olunmur.
Git-in qızıl qaydası: ümumi repozitoriya göndərilmiş commit-lərdə rebase istifadə etmə. Bu, ümumi qolda tarixçənin dəyişməz qalmasını təmin edir və digər proqramçılar təkrarlanan və ya itirilmiş commit-lərlə qarşılaşmır. Feature qolunu əsas qola inteqrasiya etmək üçün Pull Request vasitəsilə merge istifadə et.
Düzgün merge prosesi sabit proqramlaşdırmanın əsasıdır. Müasir komanda işində merge konsol vasitəsilə deyil, GitHub-da Pull Request və ya GitLab-da Merge Request vasitəsilə yerinə yetirilir. PR kod icmalından, avtomatik CI yoxlamalarından keçir və yalnız bundan sonra əsas qola birləşdirilir.
Birinci təcrübə — yalnız bütün yoxlamalar keçdikdən sonra birləşdirin. CI pipeline layihəni yığmalı, testləri işə salmalı və kod keyfiyyətini yoxlamalıdır. Hər hansı bir yoxlama keçməzsə, merge bloklanır. Müasir platformalar (GitHub, GitLab) daxili qoruma təmin edir: branch protection rules CI uğursuz olduqda merge-i avtomatik bloklayır.
İkinci təcrübə — heç vaxt pozulmuş kodu birləşdirməyin. Merge-dən əvvəl proqramçı dəyişikliklərinin build-ı pozmadığına və mövcud funksionallığı reqressiya etmədiyinə əmin olmalıdır. Bunun üçün avtomatik testlər və code review mövcuddur.
Üçüncü təcrübə — merge-dən sonra feature qollarını təmizləyin. Artıq birləşdirilmiş qol silinməlidir. Bu, qarışıqlığın qarşısını alır və repozitoriyanın zibillənməsinin qarşısını alır. GitHub PR merge-dən sonra qolu silməyi avtomatik təklif edir və repozitoriya parametrləri avtomatik silməyə konfiqurasiya edilə bilər.
Tez-tez verilən suallar
Merge — iki Git qolunu birinə birləşdirməkdir. Dəyişikliklər bir qoldan digərinə üçtərəfli birləşmə (three-way merge) vasitəsilə köçürülür. Nəticə iki valideyn commit-i olan yeni merge commit-də qeyd olunur. Merge commit hansı qolların birləşdirildiyi haqqında məlumatı saxlayır.
Merge budaqlanma tarixçəsini saxlayaraq yeni merge commit yaradır. Rebase commit-ləri digər qolun üzərinə köçürərək tarixçəni yenidən yazır, merge commit yaratmır. Rebase xətti tarixçə verir, lakin force push tələb edir. Merge ümumi qollar üçün daha təhlükəsiz, rebase şəxsi qollar üçün daha yaxşıdır.
Konfliktli faylı açın, <<<<<<<, ======= və >>>>>>> markerlərini tapın, lazımi dəyişiklikləri seçin və markerləri silin. Faylı git add ilə əlavə edin və merge-i git merge --continue ilə tamamlayın. VS Code və ya IntelliJ IDEA-da vizual həll üçün git mergetool istifadə edin.
Pull Request (və ya Merge Request) feature qolunu layihənin əsas qoluna birləşdirərkən məcburidir. PR həmkarların kod icmalından və avtomatik CI yoxlamalarından keçir. Bu müasir proqramlaşdırmanın standartıdır. Əksər layihələrdə birbaşa push main qoluna qadağandır.
Squash merge feature qolunun bütün commit-lərini merge-dən əvvəl birinə birləşdirir. Bu, əsas qolun tarixçəsini aralıq işçi commit-lərdən təmiz saxlayır. Feature qolunda çoxlu xidməti commit-lər (wip, fixes) olduqda və bütün aralıq addımları tarixçədə saxlamağa ehtiyac olmadıqda squash merge istifadə edin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun