Git
Chapters ▾ 2nd Edition

3.2 Git’də Branch - Sadə Branching və Birləşdirmə

Sadə Branching və Birləşdirmə

Real dünyada istifadə edə biləcəyiniz bir iş axını ilə branching və birləşmənin sadə bir nümunəsinə keçək. Bu addımları izləyəcəksiniz:

  1. Bir veb saytda bir az iş gör.

  2. Çalışdığınız yeni bir istifadəçi hekayəsi üçün bir branch yarat.

  3. O branch-da bəzi işlər gör.

Bu mərhələdə başqa bir məsələnin kritik olduğuna dair bir bildiriş alacaqsınız və düzəliş lazım olacaqdır. Siz aşağıdakıları edəcəksiniz:

  1. Production branch-ı seçin.

  2. Düzəliş əlavə etmək üçün bir branch yaradın.

  3. Test edildikdən sonra, düzəldici branch-ı birləşdirin və production-a push edin.

  4. Orijinal istifadəçi hekayənizə qayıdın və işə davam edin.

Sadə Branching

Əvvəlcə deyək ki, layihəniz üzərində işləyirsiniz və artıq master branch-ında bir neçə iş görmüsünüz.

Sadə commit tarixi
Figure 18. Sadə commit tarixi

Şirkətinizin istifadə etdiyi hər hansı bir izləmə sistemində 53-cü sayda çalışacağınıza qərar verdiniz. Yeni bir branch yaratmaq və eyni zamanda ona keçmək üçün -b keçidi ilə git checkout əmrini işlətmək olar:

$ git checkout -b iss53
Switched to a new branch "iss53"

Bu ssenaridir:

$ git branch iss53
$ git checkout iss53
Yeni bir branch göstəricisi yaratmaq
Figure 19. Yeni bir branch göstəricisi yaratmaq

Veb saytınızda işləyirsiniz və bəzi commit-lər verirsiniz. Bunu etmək, iss53 branch-ını irəli aparır, çünki siz onu yoxlamısınız (yəni HEAD ona işarə edir):

$ vim index.html
$ git commit -a -m 'Create new footer [issue 53]'
`iss53` branch-ı işinizlə irəlilədi
Figure 20. iss53 branch-ı işinizlə irəlilədi

İndi veb saytında bir problem olduğuna dair zəng alırsınız və dərhal onu düzəltməlisiniz. Git ilə düzəlişlərinizi iss53 dəyişiklikləri ilə birlikdə düzəltməyə ehtiyac yoxdur və düzəlişlərinizi production-da olanlara tətbiq etməzdən əvvəl bu dəyişiklikləri geri qaytarmaq üçün əziyyət çəkməyinizə ehtiyac yoxdur. Sadəcə master branch-ına qayıtmaq lazımdır.

Ancaq bunu etməzdən əvvəl qeyd edin ki, əgər işlədiyiniz qovluq və ya quruluş sahəniz yoxlanılan branch-la konfilikt təşkil etmirsə, Git branch-ları dəyişməyə imkan vermir. Branch-ları dəyişdirərkən təmiz bir iş vəziyyətinə sahib olmağınız yaxşıdır. Daha sonra Stashing və Təmizləmə-də bəhs edəcəyimiz (yəni stashing və commit etmək) yolları var. Hələlik, bütün dəyişikliklərinizi etdiyinizi düşünün və yenidən master branch-ınıza qayıda bilərsiniz:

$ git checkout master
Switched to branch 'master'

Bu anda layihə işlədiyiniz qovluq #53 nömrəli problem üzərində işləməyə başlamamışdan əvvəlki yoldur və fikrinizi düzəlişə cəmləşdirə bilərsiniz. Bu yadda saxlamağınız vacib olan bir məqamdır: branch-ları dəyişdirdiyiniz zaman Git, işçi qovluğunuzu bu branch-da sonuncu dəfə etdiyiniz kimi görmək üçün sıfırlayır. Bu işləmə kopyasının branch-ının son commit-ə bənzədiyinə əmin olmaq üçün faylları əlavə edir, çıxarır və avtomatik olaraq dəyişdirir.

Sonra düzəltmək üçün düzəltmə nöqtəniz var. Gəlin tamamlanana qədər işləyəcək bir hotfix branch-ı yaradaq:

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'Fix broken email address'
[hotfix 1fb7853] Fix broken email address
 1 file changed, 2 insertions(+)
`master` əsasında Hotfix branch-ı
Figure 21. master əsasında Hotfix branch-ı

Testlərinizi işə sala bilərsiniz,hansı düzəlişi istədiyinizdən əmin olun və nəhayət hotfix branch-ını istehsal etmək üçün yenidən master branch-ınıza birləşdirin.

Siz bunu git merge əmri ilə edin:

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

Bu birləşmədə “fast-forward” ifadəsini görəcəksiniz. Birləşdirdiyiniz hotfix branch-ı ilə göstərilən C4`commit-i, üzərində olduğunuz `C2 commit-inin qabağında olduğundan Git sadəcə göstəricini irəli aparır. Başqa bir şəkildə ifadə etmək üçün ilk commit-in tarixini izləməklə əldə edilə bilən bir commit-lə birləşməyə çalışdığınız zaman, Git göstərici irəli apararaq işləri sadələşdirir, çünki birlikdə birləşmək üçün ayrı-ayrılıqda işlər görülmür - buna deyilir “fast-forward.”

Dəyişiklik artıq master branch-nın işarə etdiyi commit-in snapshotudur və düzəlişi yerləşdirə bilərsiniz.

`master` sürətli şəkildə `hotfix`-ə yönləndirilir
Figure 22. master sürətli şəkildə hotfix-ə yönləndirilir

Super əhəmiyyətli düzəlişiniz yerləşdirildikdən sonra müdaxilə etməmişdən əvvəl etdiyiniz işə geri dönməyə hazırsınız.

Ancaq əvvəlcə hotfix branch-nı silirsiniz, çünki artıq ehtiyacınız yoxdur - master branch-ı eyni yeri göstərir.

Onu -d seçimini git branch əmrinə əlavə edərək silə bilərsiniz:

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

İndi #53 nömrəli məsələ ilə əlaqədar işinizdə olan şöbəyə qayıda bilərsiniz və üzərində işləməyə davam edə bilərsiniz.

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'Finish the new footer [issue 53]'
[iss53 ad82d7a] Finish the new footer [issue 53]
1 file changed, 1 insertion(+)
`iss53` üzərində işləməyə dəvam etmək
Figure 23. iss53 üzərində işləməyə dəvam etmək

Burada qeyd etmək lazımdır ki, hotfix branch-da gördüyünüz işlər iss53 branch-dakı sənədlərdə yoxdur. Əgər onu pull etmək lazımdırsa, git merge master-i işə salmaqla master branch-nızı iss53 branch-a birləşdirə bilərsiniz və ya iss53 branch-nı daha sonra master halına gətirməyə qərar verənə qədər bu dəyişikliklərin inteqrasiyasını gözləyə bilərsiniz.

Sadə Birləşdirmə

Təqdim etdiyiniz #53 nömrəli işiniz tamamlandı və master branch-nıza birləşdirilməyə artıq hazırdır. Bunu etmək üçün, iss53 branch-nızı əvvəllər hotfix branch-nı birləşdirdiyiniz kimi master-ə birləşdirəcəksiniz. Yalnız etməli olduğunuz branch-ı yoxlamaq və sonra git merge əmrini icra etməkdir:

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

Bu əvvəl düzəltdiyiniz hotfix birləşməsindən bir az fərqli görünür. Bu vəziyyətdə inkişaf tarixiniz bəzi köhnə nöqtələrdən ayrılacaqdır. Gördüyünüz branch-dakı commit birləşdiyiniz branch-ın birbaşa ancestor-u olmadığından Git bəzi işlər görməlidir. Bu vəziyyətdə Git branch ucları və ikisinin ortaq ancestor-u ilə göstərilən iki snapshot-u istifadə edərək sadə üç tərəfli birləşmə edir.

Tipik birləşmədə istifadə olunan üç snapshot
Figure 24. Tipik birləşmədə istifadə olunan üç snapshot

Branch göstərişini irəli sürmək əvəzinə, Git bu üç tərəfli birləşmənin nəticəsi olan yeni bir görüntü yaradır və avtomatik olaraq ona işarə edən yeni bir commit yaradır. Bu birləşmə commit-i adlandırılır və birdən çox ancestor-un olması ilə xüsusi olur.

Birləşmə commit-i
Figure 25. Birləşmə commit-i

İndi işiniz birləşdirildikdən sonra iss53 branch-ına ehtiyacınız yoxdur. Məsələni izləmə sisteminizdə bağlaya və branch-ı silə bilərsiniz:

$ git branch -d iss53

Əsas Birləşmə Konfiliktləri

Bəzən bu proses əngəlsiz getmir. Birləşdirdiyiniz iki branch-da eyni faylın eyni hissəsini fərqli şəkildə dəyişsəniz, Git onları təmiz birləşdirə bilməyəcək. Əgər #53 nömrəli məsələ ilə bağlı düzəlişiniz hotfix branch-ı kimi bir faylın eyni hissəsini dəyişdirsə, bu kimi bir şeyə bənzər birləşmə konflikti alacaqsınız:

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Git avtomatik olaraq yeni birləşmə commit-i yaratmadı. Və konflikti həll edərkən prosesi dayandırdı. Birləşmə konfliktindən sonra hər hansı bir nöqtədə hansı sənədlərin açılmadığını görmək istəyirsinizsə, git status-u istifadə edə bilərsiniz:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

Konfiliktləri birləşdirən və həll edilməmiş hər hansı bir şey əlaqələndirilməmiş kimi verilmişdir. Git, konfliktləri olan fayllara standart konflikt həll etmə işarələrini əlavə edir, onları manual aça və bu konfiliktləri həll edə bilərsiniz. Faylınızda bənzər bir hissə var:

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

Bu HEAD`dakı versiya (sizin `master branch-nız, çünki birləşmə əmrinizi icra edərkən yoxladığınız şey bu idi) blokun yuxarı hissəsidir (=======-dən yuxarıdakı hər şey), iss53 branch-nızdakı versiya alt hissədəki hər şeyə bənzəyir.

Konflikti həll etmək üçün ya bir tərəfi,ya da digərini seçməlisiniz və ya özünüzü birləşdirməlisiniz.

Məsələn, bütün bloku aşağıdakı ilə əvəz etməklə bu konflikti həll edə bilərsiniz:

<div id="footer">
please contact us at email.support@github.com
</div>

Bu həll yolunuz hər hissəsində bir az var və <<<<<<<, =======>>>>>>> sətirləri tamamilə çıxarıldı. Hər bir konflikt faylda bu bölmələrin hər birini həll etdikdən sonra, həll olunduğunu qeyd etmək üçün hər bir fayl üzərində git add edin. Faylın səhnələşdirilməsi Git-də həll olunduğu kimi qeyd olunur.

Bu problemləri həll etmək üçün bir qrafik vasitədən istifadə etmək istəyirsinizsə, uyğun vizual birləşmə vasitəsini işə salan və qarşıdurmalardan keçən git mergetool işlədə bilərsiniz:

$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):

Standartdan başqa bir birləşmə vasitəsini istifadə etmək istəyirsinizsə (əmr Mac-də işlədiyi üçün Git bu vəziyyətdə opendiff seçdi), aşağıdakı alətlərdən birini istifadə etdikdən sonra yuxarıda sadalanan bütün dəstəklənən alətləri görə bilərsiniz. İstədiyiniz vasitənin adını yazın.

Note

Çətin birləşmə konfliktlərini həll etmək üçün daha inkişaf etmiş vasitələrə ehtiyacınız varsa, İnkişaf etmiş Birləşmə bölməsində daha çox məlumat veririk.

Birləşmə alətindən çıxdıqdan sonra Git birləşmənin uğurlu olub olmadığını soruşur. Skriptin olduğunu söyləsəniz, sənədin sizin üçün həll olunduğunu qeyd etmək üçün mərhələləndirir. Bütün konfliktlərin həll olunduğunu təsdiqləmək üçün yenidən `git status ` tətbiq edə bilərsiniz:

$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html

Bundan məmnun olsanız və konflikt ilə əlaqəli hər şeyin səhnəyə qoyulduğunu təsdiqləsəniz, birləşmə commitini yekunlaşdırmaq üçün git commit yazın. Varsayılan mesaj bu şəkildə olacaqdır:

Merge branch 'iss53'

Conflicts:
    index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#	.git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#	modified:   index.html
#

Gələcəkdə bu birləşməyə baxan başqalarına faydalı olacağını düşünürsənsə, birləşmə məsələsini necə həll etdiyiniz barədə təfərrüatları olan bu mesajı dəyişdirə bilərsiniz və ya bunlar aydın deyilsə, etdiyiniz dəyişiklikləri niyə etdiyinizi izah edə bilərsiniz.