-
1. Başlanğıc
- 1.1 Versiyaya Nəzarət Haqqında
- 1.2 Git’in Qısa Hekayəsi
- 1.3 Git Nədir?
- 1.4 Əmr Sətiri
- 1.5 Git’i Quraşdırmaq
- 1.6 İlk Dəfə Git Quraşdırması
- 1.7 Kömək Almaq
- 1.8 Qısa Məzmun
-
2. Git’in Əsasları
-
3. Git’də Branch
- 3.1 Nutshell’də Branch’lar
- 3.2 Sadə Branching və Birləşdirmə
- 3.3 Branch İdarəedilməsi
- 3.4 Branching İş Axınları
- 3.5 Uzaq Branch’lar
- 3.6 Rebasing
- 3.7 Qısa Məzmun
-
4. Server’də Git
- 4.1 Protokollar
- 4.2 Serverdə Git Əldə Etmək
- 4.3 Sizin öz SSH Public Key’nizi yaratmaq
- 4.4 Server qurmaq
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Üçüncü Tərəf Seçimləri
- 4.10 Qısa Məzmun
-
5. Paylanmış Git
-
6. GitHub
-
7. Git Alətləri
- 7.1 Reviziya Seçimi
- 7.2 Interaktiv Səhnələşdirmə
- 7.3 Stashing və Təmizləmə
- 7.4 İşinizin İmzalanması
- 7.5 Axtarış
- 7.6 Tarixi Yenidən Yazmaq
- 7.7 Reset Demystified
- 7.8 İnkişaf etmiş Birləşmə
- 7.9 Rerere
- 7.10 Git ilə Debugging
- 7.11 Alt Modullar
- 7.12 Bundling
- 7.13 Dəyişdirmək
- 7.14 Etibarlı Yaddaş
- 7.15 Qısa Məzmun
-
8. Git’i Fərdiləşdirmək
- 8.1 Git Konfiqurasiyası
- 8.2 Git Atributları
- 8.3 Git Hook’ları
- 8.4 Git-Enforced Siyasət Nümunəsi
- 8.5 Qısa Məzmun
-
9. Git və Digər Sistemlər
- 9.1 Git Müştəri kimi
- 9.2 Git’ə Miqrasiya
- 9.3 Qısa Məzmun
-
10. Git’in Daxili İşləri
- 10.1 Plumbing və Porcelain
- 10.2 Git Obyektləri
- 10.3 Git Referansları
- 10.4 Packfile’lar
- 10.5 Refspec
- 10.6 Transfer Protokolları
- 10.7 Maintenance və Məlumatların Bərpası
- 10.8 Mühit Dəyişənləri
- 10.9 Qısa Məzmun
-
A1. Appendix A: Digər Mühitlərdə Git
- A1.1 Qrafik interfeyslər
- A1.2 Visual Studio’da Git
- A1.3 Visual Studio Code’da Git
- A1.4 Eclipse’də Git
- A1.5 Sublime Text’də Git
- A1.6 Bash’da Git
- A1.7 Zsh’də Git
- A1.8 PowerShell’də Git
- A1.9 Qısa Məzmun
-
A2. Appendix B: Proqramlara Git Daxil Etmək
- A2.1 Əmr-sətri Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Appendix C: Git Əmrləri
- A3.1 Quraşdırma və Konfiqurasiya
- A3.2 Layihələrin Alınması və Yaradılması
- A3.3 Sadə Snapshotting
- A3.4 Branching və Birləşmə
- A3.5 Layihələrin Paylaşılması və Yenilənməsi
- A3.6 Yoxlama və Müqayisə
- A3.7 Debugging
- A3.8 Patching
- A3.9 E-poçt
- A3.10 Xarici Sistemlər
- A3.11 İdarəetmə
- A3.12 Plumbing Əmrləri
3.6 Git’də Branch - Rebasing
Rebasing
Git’də dəyişiklikləri bir budaqdan digərinə birləşdirməyin iki əsas yolu var: merge
və rebase
.
Bu bölmədə rebase-in nə olduğunu, bunu necə edəcəyinizi, niyə olduqca gözəl bir vasitədir və hansı hallarda istifadə etmək istəmədiyinizi öyrənəcəksiniz.
Sadə Rebase
Əvvəlki bir nümunəyə qayıtsanız Sadə Birləşdirmə, işinizi bölüşdürdüyünüzü və iki fərqli branch-da qərar verdiyinizi görə bilərsiniz.
Branch-ları birləşdirməyin ən asan yolu, yuxarıda bəhs etdiyimiz kimi, merge
əmridir.
İki ən son branch snapshotu (C3
və` C4`) və ikisinin ən son ortaq ancestor-u (C2
) arasında üç tərəfli birləşmə həyata keçirir, yeni bir snapshot yaradır (və commit edir).
Ancaq başqa bir yol var: C4
-də təqdim edilən dəyişikliyin patch-ını götürüb C3
-ün üstünə yenidən tətbiq edə bilərsiniz.
Git-də buna rebasing deyilir.
rebase
əmri ilə bir branch-da edilmiş bütün dəyişiklikləri götürüb başqa bir branch-da təkrarlaya bilərsiniz.
Bu misal üçün experiment
branch-ını yoxlayıb, master
branch-a aşağıdakı kimi qaytarın:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
Bu əməliyyat iki branch-ın ortaq ancestor-una (birinə davam etdiyiniz və birinə rebasing etdiyiniz) gedərək işləyir,olduğunuz branch-ın hər bir commit-i tərəfindən təqdim olunan fərqləri əldə edərək, həmin fərqləri müvəqqəti sənədlərdə saxlayaraq işləyir, hazırkı branch-ı yenidən düzəltdiyiniz branch-la eyni commit-ə bərpa edin və nəhayət hər dəyişikliyi öz növbəsində tətbiq edin.
C4`də `C3
-ə edilən dəyişikliyin rebasing edilməsiBu nöqtədə, master
branch-a qayıda və sürətli bir şəkildə birləşə bilərsiniz.
$ git checkout master
$ git merge experiment
master
branch-ıİndi C4
-ün işarələdiyi snapshot <the merge example-də C5
ilə işarələnmiş snapshotla eynidir.
İnteqrasiyanın son məhsulu arasında heç bir fərq yoxdur, lakin rebasing daha təmiz bir tarix yaradır.
Rebase edilmiş bir branch-ın log-larını araşdırsanız, xətti bir tarixə bənzəyir: görünür ki, bütün işlər əvvəlcə paralel olaraq baş versə də, bütün işlərin ardıcıllıqla baş verdiyi anlaşılır.
Tez-tez verdiyiniz tapşırıqların uzaq bir branch-a təmiz tətbiq olunmasını təmin etmək üçün bunu edəcəksiniz - töhfə verməyə çalışdığınız, ancaq qorumadığınız bir layihədə.
Bu vəziyyətdə işinizi bir branch-da edər və sonra patch-larını əsas layihəyə təqdim etməyə hazır olduğunuz zaman işinizi origin/master
-ə ya dəyişdirərdiniz.
Bu yolla, qoruyucu heç bir inteqrasiya işi görməməlidir - sadəcə irəli və ya təmiz tətbiq olunmalıdır.
Diqqət yetirin ki, başa çatdığınız son commit-in göstərildiyi snapshot, istər bir düzəltmə əmrinin sonuncusu olsun, istərsə birləşmədən sonra edilən son birləşmə, eyni Rebasing dəyişikliklərini bir iş xəttindən digərinə təqdim edilmiş qaydada dəyişdirir, birləşmə isə son nöqtələri götürərək onları birləşdirir.
Daha Maraqlı Rebase-lər
Ayrıca, rebase hədəf branch-ında başqa bir şeydə yenidən istifadə edə bilərsiniz.
Məsələn, Başqa bir mövzu branch-ından bir mövzu branch-a olan bir tarix kimi bir tarix çəkin.
Layihəinizə bəzi server tərəfi funksionallıq əlavə etmək üçün bir mövzu branch-nı (server
) əlavə etdiniz və commit yaratdınız.
Sonra müştəri tərəfində dəyişiklik etmək üçün (client
) branch-ı düzəldin və bir neçə dəfə commit edin.
Nəhayət, yenidən server branch-ınıza qayıtdınız və daha bir neçə commit etdiniz.
Tutaq ki, bir müştəri tərəfindəki dəyişiklikləri sərbəst buraxmaq üçün ana xəttinizə birləşdirmək istədiyinizə qərar verirsiniz, ancaq daha sonra sınaqdan keçirilməyincə server tərəfindəki dəyişiklikləri dayandırmaq istəyərsiniz.
server
-də (` C8` və C9
) olmayan client
-dəki dəyişiklikləri götürüb git rebase
-in --onto
seçimini istifadə edərək master
branch-ındə təkrarlaya bilərsiniz:
$ git rebase --onto master server client
Bu, əsasən ‘` client' branch-nı götürün, `server
branch-ından ayrıldığından patch-ları müəyyənləşdirin və bu patch-ları client
branch-ında birbaşa master
branch-ından kənarda qurulmuş kimi təkrarlayın . '’
Biraz mürəkkəb olsa da, amma nəticə olduqca gözəldir.
İndi master
branch-ınızı sürətlə irəliləyə apara bilərsiniz ( Client branch-ındakı dəyişiklikləri daxil etmək üçün master
branch-ınızı sürətli yönləndirin-ə bax):
$ git checkout master
$ git merge client
master
branch-ınızı sürətli yönləndirinDeyək ki, həm də server branch-nızı pull etməyə qərar verdiniz. git rebase <basebranch> <topicbranch>
-ı işə salmaqdan əvvəl server
branch-ını master
branch -a rebase edə bilərsiniz. Mövzu branch-nı yoxlayır (bu vəziyyətdə, server
) və əsas branch-a (master
) qaytarır.
$ git rebase master server
Bu, server
işinizi master
işinizin üstündə, Server branch-nızı master
branch-nızın üstünə rebasing etmək-da göstərildiyi kimi təkrarlayır.
master
branch-nızın üstünə rebasing etməkSonra əsas branch-ı (master
) sürətlə irəli sürə bilərsiniz:
$ git checkout master
$ git merge server
Bütün işlər inteqrasiya olunduğuna görə, client
və server
branch-larını silə bilərsiniz, bu da bütün bu proses üçün tarixinizi Son commit tarixi kimi qoyur:
$ git branch -d client
$ git branch -d server
Rebasing-in Təhlükələri
Ahh, lakin çatışmazlıqlar olmadan rebasing-in zövqü olmaz,hansı ki onları bir sətirdə yekunlaşdırmaq olar.
Depolarınızdan kənarda mövcud olan və insanların üzərində işləyə bildikləri commitləri rebase etməyin.
Bu qaydaya əməl etsəniz, yaxşı olacaqsınız. Bunu etməsəniz, insanlar sizə nifrət edəcəklər və dostlarınız və ailəniz tərəfindən rüsvay olacaqsınız.
Əşyaları rebase etdiyinizdə mövcud commit-lərdən imtina edirsiniz və oxşar, lakin fərqli olanları yaradırsınız.
Əgər commit-ləri bir yerə push etsəniz və başqaları onları aşağı pull edib üzərində işləyirsə, sonra git rebase
ilə yenidən yazıb yenidən push etsəniz, iş yoldaşların işlərini yenidən birləşdirməyə məcbur olacaqlar və işləriniz qarışıq olacaq. Ona görə işlərini özünüzə qaytarmağa çalışın.
Öublic etdiyiniz işin rebasing olunanda problem yarada biləcəyinə dair bir nümunəyə baxaq. Tutaq ki, mərkəzi bir serverdən klonlaşdırırsınız və daha sonra bir az iş görürsünüz.
Commit tarixçəniz belə görünür:
İndi başqası birləşməyi əhatə edən daha çox iş görür və mərkəzi serverə işləyir. Siz götürün və yeni uzaq branch-ı işinizə birləşdirərək tarixinizi bu kimi bir hala gətirin:
Sonra birləşən işi push edən şəxs geri qayıtmağı və işlərini dəyişdirməyi qərara alır; serverdəki tarixi yenidən yazmaq üçün git push --force
tətbiq edirlər.
Daha sonra yeni commit-ləri gətirərək həmin serverdən alırsınız.
İndi ikiniz də turşu içindəsiniz.
Bir git pull
etsəniz, tarixin hər iki xəttini özündə birləşdirən birləşmə əməliyyatı yaradacaqsınız və depo bu cür görünəcək:
Tarixiniz bu kimi görünəndə git log
işlədirsinizsə, qarışıqlıq yaradan eyni müəllif, tarix və mesajı olan iki commit görürsünüz.
Bundan əlavə, bu tarixi yenidən serverə push etsəniz, insanları qarışdıra biləcək bütün əvəz edilmiş sənədləri mərkəzi serverə yenidən təqdim etmiş olacaqsınız.
Digər developerin C4
və C6
-ların tarixdə olmasını istəmədiyini güman etmək olduqca təhlükəsizdir; buna görə ilk növbədə yenidən çap etdilər.
Rebase etdiyiniz zaman yenidən yazın
Əgər belə bir vəziyyətdə özünüzü taparsanız, Git sizə kömək edə biləcək daha bir sehrə sahibdir. Əgər komandanızdakı kimsə işə əsaslandığınız işin üzərində yazılan dəyişiklikləri push edirsə, problem sizin kim olduğunuzu və yenidən yazdıqlarını anlamaqdır.
Məlum olub ki, SHA-1 yoxlama cədvəlinə əlavə olaraq, Git yalnız commit ilə təqdim olunan patch-a əsaslanan bir çek məbləğini də hesablayır. Buna “patch-id” deyilir.
Yenidən yazılmış işi pull doün etsəniz və tərəfdaşınızdan aldığınız yeni işin üstünə yazsanız, Git tez-tez misilsiz sizin nəyi başa düşdüyünüzü yeni branch-ın üstünə tətbiq edə bilər.
Məsələn, əvvəlki ssenaridə, əgər Kimsə işinizə əsaslanaraq verdiyiniz commit-ləri tərk edərək, rebase edilmiş commit-ləri push edir olduğumuz zaman birləşmə yerinə git rebase teamone/master
işlədiriksə, Git:
-
Branch-ımız üçün hansı işin özünəməxsus olduğunu müəyyənləşdirin (C2, C3, C4, C6, C7)
-
Hansıların birləşmədiyini təyin edin (C2, C3, C4)
-
Hədəf branch-ına yenidən yazılmayanları təyin edin (C4 C4 'ilə eyni patch olduğundan)
-
Bu commit-ləri
teamone/master
başına tətbiq edin
Beləliklə, Eyni işdə yenidən yeni birləşmə commit-nə qoşulursunuz-də gördüyümüz nəticənin əvəzinə daha çox Force-pushed rebase işə yenidən başlayın kimi bir şeylə nəticələnərdik.
Bu yalnız ortağınızın hazırladığı C4
və C4'
demək olar ki, eyni bir patch olduqda işləyir.
Əks təqdirdə, yenidən yükləmə bunun bir dublikat olduğunu söyləyə bilməyəcək və başqa bir C4-ə bənzər bir yamaq əlavə edəcəkdir (ehtimal ki, təmiz tətbiq olunmayacaq, çünki dəyişikliklər heç olmasa orada olacaq).
Normal bir git pull
yerinə git pull --rebase
işlətməklə bunu asanlaşdıra bilərsiniz.
Və ya bu vəziyyətdə git rebase teamone/master
ardınca git fetch
ilə manual edə bilərsiniz.
git pull
istifadə edirsinizsə və --rebase
standart etmək istəyirsinizsə, git config --global pull.rebase true
kimi bir şey ilə pull.rebase
konfiqurasiya dəyərini təyin edə bilərsiniz.
Heç vaxt öz kompüterinizi tərk etməyən commit-ləri yenidən yerinə yetirsəniz, yaxşı olacaqsınız. Əgər push etdiyiniz commit-ləri geri qaytarsanız, lakin başqa heç kim əsas götürməmişsə, həmçinin yaxşı olacaqsınız. Əgər siz əvvəlcədən ictimailəşdirilmiş commit-ləri geri qaytarsanız və insanlar bu commit-ləri əsas götürsələr, o zaman bəzi narahat problemlərə və komanda yoldaşlarınızın qınağına düşə bilərsiniz.
Əgər siz və ya tərəfdaş bir anda zəruri hesab edirsinizsə,hər kəsin git pull --rebase
işlətdiyini bildiyinizdən əmin olun ki, bu da bir az daha sadə olur.
Rebase vs Birləşdirmək
İndi siz rebasing və birləşdirmə hərəkətlərini gördünüz, hansının daha yaxşı olduğunu düşünə bilərsiniz. Buna cavab verməzdən əvvəl bir az geri çəkilib tarixin nə demək olduğunu danışaq.
Bu baxımdan bir məqam odur ki, depozit tarixçənizin tarixçəsi əslində baş verənlərin qeydidir. Tarixi bir sənəddir, öz dəyərindədir və dəyişdirilməməlidir. Bu baxımdan, commit tarixinin dəyişdirilməsi demək olar ki, küfrdür; əslində nəyi ötürdüyünüz barədə lying danışırsınız. Birləşməyin qarışıq sıra seriyası varsa nə olacaq? Bu belə oldu və depoları bunu sonrakı nəsillər üçün saxlamalıdır.
Qarşı nöqtə, commit tarixinin olmasıdır, yəni layihənizin necə edildiyi haqqında hekayədir.
Bir kitabın ilk layihəsini yayımlamazsınız və proqramınızı necə qoruyacağınıza dair təlimat diqqətlə redaktəyə etməlisiniz.
Bu, hekayəni gələcək oxuculara ən yaxşı şəkildə izah etmək üçün rebase
və filter-branch
kimi vasitələrdən istifadə edən düşərgədir.
İndi gələk birləşməyin və ya rebasing etməyin daha yaxşı olması sualına: ümid edirik bunun asan olmadığını görərsiniz. Git güclü bir vasitədir və tarixinizlə birlikdə çox şey etməyə imkan verir, lakin hər komanda və hər layihə fərqlidir.
Artıq hər ikisinin necə işlədiyini bildiyinizdən, hansınızın vəziyyətiniz üçün ən uyğun olduğunu qərar verməyiniz sizə bağlıdır.
Ümumiyyətlə, hər iki dünyanın ən yaxşısını qazanmağın yolu hekayənizi təmizləmək üçün onları təkzib etmədən əvvəl etdiyiniz, lakin hələ paylaşmadığınız yerli dəyişiklikləri geri qaytarmaqdır.