-
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
A2.2 Appendix B: Proqramlara Git Daxil Etmək - Libgit2
Libgit2
Sərəncamınızdakı başqa bir seçim də Libgit2 istifadə etməkdir. Libgit2, digər proqramların daxilində istifadə üçün gözəl bir API-yə sahib olmağa yönəlmiş Git’in asılılıqsız bir tətbiqidir. https://libgit2.orgsaytında tapa bilərsiniz.
Əvvəlcə C API-nin nə olduğuna nəzər salaq. Və budur, qasırğa turu:
// Open a repository
git_repository *repo;
int error = git_repository_open(&repo, "/path/to/repository");
// Dereference HEAD to a commit
git_object *head_commit;
error = git_revparse_single(&head_commit, repo, "HEAD^{commit}");
git_commit *commit = (git_commit*)head_commit;
// Print some of the commit's properties
printf("%s", git_commit_message(commit));
const git_signature *author = git_commit_author(commit);
printf("%s <%s>\n", author->name, author->email);
const git_oid *tree_id = git_commit_tree_id(commit);
// Cleanup
git_commit_free(commit);
git_repository_free(repo);
İlk iki sətir Git deposunu açır.
git_repository
növü, yaddaşdakı cache-a sahib bir deponun idarəedicisini təmsil edir.
Deponun iş qovluğuna və ya .git
qovluğuna gedən yolu dəqiq bildiyiniz zaman bu ən sadə metoddur.
Axtarış üçün seçimləri ehtiva edən git_repository_open_ext
-də var, git_clone
və uzaq bir deponun yerli klonunu hazırlayan dostlar,
və tamamilə yeni bir depo yaratmaq üçün git_repository_init
istifadə olunur.
Kodun ikinci hissəsi, HEAD-in sonunda göstərdiyi commit-i əldə etmək üçün rev-parse sintaksisindən istifadə edir (bu barədə daha çox məlumat üçün Branch Referansları bax).
Geri qaytarılmış tip, bir depo üçün Git obyekt bazasında mövcud olanı təmsil edən git_object
göstəricisidir.
git_object
əslində bir neçə müxtəlif növ obyekt üçün “parent” növüdür; “child” növlərinin hər biri üçün yaddaş düzəni, git_object
ilə eynidir, buna görə də doğru birinə ata bilərsiniz.
Bu vəziyyətdə, git_object_type(commit)
GIT_OBJ_COMMIT
qaytarır,buna görə git_commit
göstəricisinə ötürülməsi təhlükəsizdir.
Növbəti hissə, commit-in xüsusiyyətlərinə necə çatacağını göstərir.
Buradakı son sətirdə git_oid
növü istifadə olunur; bu Libgit2’nin bir SHA-1 hash üçün təqdimatıdır.
Bu nümunədən bir-iki pattern ortaya çıxmağa başladı:
-
Bir göstərici elan etsəniz və bir referansı Libgit2 çağırışına göndərsəniz, bu çağırış, ehtimal ki, tam bir error kodu qaytaracaqdır. A `0 'dəyəri müvəffəqiyyəti göstərir; daha az bir şey səhvdir.
-
Libgit2 sizin üçün bir göstəricini doldurursa, onu sərbəst buraxmağa cavabdehsiniz.
-
Libgit2 bir çağırışdan
const
göstəricisini qaytarırsa, onu sərbəst buraxmanız lazım deyil, ancaq aid olduğu obyekt sərbəst buraxıldıqda etibarsız olacaqdır. -
C yazmaq biraz ağrılıdır.
Bu son, Libgit2 istifadə edərkən C yazacağınızın çox ehtimal olunmadığını göstərir. Xoşbəxtlikdən, xüsusi dilinizdən və mühitinizdən Git depoları ilə işləməyi asanlaşdıran bir sıra dilə bağlı bağlamalar mövcuddur. Güclü adlanan və https://github.com/libgit2/rugged ünvanında olan Libgit2 üçün Ruby bağlayıcılarından istifadə edərək yazılmış yuxarıdakı nümunəyə nəzər salaq.
repo = Rugged::Repository.new('path/to/repository')
commit = repo.head.target
puts commit.message
puts "#{commit.author[:name]} <#{commit.author[:email]}>"
tree = commit.tree
Gördüyünüz kimi, kod daha az qarışıqdır.
Birincisi, Rugged istisnalardan istifadə edir; səhv şərtlərinə siqnal vermək üçün ConfigError
və ya ObjectError
kimi şeyləri qaldıra bilər.
İkincisi, resursların açıq şəkildə sərbəst buraxılması yoxdur, çünki Ruby garbage-collected-dir.
Bir az daha mürəkkəb bir nümunəyə nəzər salaq: sıfırdan commit hazırlamaq
blob_id = repo.write("Blob contents", :blob) # (1)
index = repo.index
index.read_tree(repo.head.target.tree)
index.add(:path => 'newfile.txt', :oid => blob_id) # (2)
sig = {
:email => "bob@example.com",
:name => "Bob User",
:time => Time.now,
}
commit_id = Rugged::Commit.create(repo,
:tree => index.write_tree(repo), # (3)
:author => sig,
:committer => sig, # (4)
:message => "Add newfile.txt", # (5)
:parents => repo.empty? ? [] : [ repo.head.target ].compact, # (6)
:update_ref => 'HEAD', # (7)
)
commit = repo.lookup(commit_id) # (8)
-
Yeni bir faylın məzmunu olan yeni bir blob yaradın.
-
İndeksi başlıqlı commit ağac ilə doldurun və yeni faylı
newfile.txt
yoluna əlavə edin. -
Bu, ODB-də yeni bir ağac yaradır və onu yeni commit üçün istifadə edir.
-
Həm müəllif, həm də müəllif sahələri üçün eyni imzanı istifadə edirik.
-
Commit mesajı.
-
Commit yaradarkən, yeni commit-in valideynlərini göstərməlisiniz. Bu, tək valideyn üçün HEAD tip-indən istifadə edir.
-
Rugged (və Libgit2) bir öhdəlik götürərkən istəyə görə bir referansı yeniləyə bilər.
-
Qayıdış dəyəri yeni bir əmr obyekti olan SHA-1 hash-ıdır, bundan sonra
Commit
obyektini əldə etmək üçün istifadə edə bilərsiniz.
Ruby kodu gözəl və təmizdir, lakin Libgit2 heavy lifting etdiyindən bu kod da çox sürətli işləyəcəkdir. Rubyist deyilsinizsə, Other Bindings bəzi digər bağlantılara toxunuruq.
Ətraflı funksionallıq
Libgit2, Git əsas xaricində olmayan bir neçə xüsusiyyətə malikdir. Bir nümunə taxıla biləndir: Libgit2, bir neçə növ əməliyyat üçün xüsusi “arxa planlar” təmin etməyə imkan verir, beləliklə şeyləri Git-dən fərqli bir şəkildə saxlaya bilərsiniz. Libgit2, digər şeylər arasında, konfiqurasiya, ref storage və obyekt verilənlər bazası üçün xüsusi geri imkanları verir.
Gəlin bunun necə işlədiyini nəzərdən keçirək. Aşağıdakı kod, Libgit2 komandası tərəfindən təmin edilmiş geri nümunələr toplusundan götürüldü ( https://github.com/libgit2/libgit2-backends). Obyekt databazası üçün xüsusi bir geribildirim necə qurulur:
git_odb *odb;
int error = git_odb_new(&odb); // (1)
git_odb_backend *my_backend;
error = git_odb_backend_mine(&my_backend, /*…*/); // (2)
error = git_odb_add_backend(odb, my_backend, 1); // (3)
git_repository *repo;
error = git_repository_open(&repo, "some-path");
error = git_repository_set_odb(repo, odb); // (4)
Səhvlərin tutulduğunu, ancaq handle edilmədiyini unutmayın. Ümid edirik ki, kodunuz bizimkindən daha yaxşıdır.__
-
Həqiqi işi görənlər “backends” üçün konteyner rolunu oynayacaq boş bir obyekt verilənlər bazasını (ODB) “frontend”-i işə salın.
-
Xüsusi bir ODB backendi başlatın.
-
Backend-i frontend-ə əlavə edin.
-
Bir depo açın və obyektləri axtarmaq üçün ODB-dən istifadə edəcəyik.
Bəs bu git_odb_backend_mine
nədir?
Yaxşı, bu öz ODB həyata keçirməyiniz üçün konstruktordur və git_odb_backend
quruluşunu düzgün doldurduqca orada istədiyinizi edə bilərsiniz.
Budur nəyə bənzədiyinə baxaq:
typedef struct {
git_odb_backend parent;
// Some other stuff
void *custom_context;
} my_backend_struct;
int git_odb_backend_mine(git_odb_backend **backend_out, /*…*/)
{
my_backend_struct *backend;
backend = calloc(1, sizeof (my_backend_struct));
backend->custom_context = …;
backend->parent.read = &my_backend__read;
backend->parent.read_prefix = &my_backend__read_prefix;
backend->parent.read_header = &my_backend__read_header;
// …
*backend_out = (git_odb_backend *) backend;
return GIT_SUCCESS;
}
Buradakı ən incə bir məhdudiyyət, budur ki my_backend_struct
-ın ilk üzvü git_odb_backend
quruluşu olmalıdır; bu yaddaş sxeminin Libgit2 kodunun olmasını gözlədiyini təmin edir.
Qalan hissəsi özbaşınadır; bu quruluş lazım olduğunuz qədər böyük və ya kiçik ola bilər.
Başlatma funksiyası quruluş üçün bir az yaddaş ayırır, xüsusi kontekst qurur və sonra dəstəklədiyi parent
strukturunun üzvlərini doldurur.
Tam çağırış imzaları dəsti üçün Libgit2 mənbəyindəki include/git2/sys/odb_backend.h
faylına nəzər yetirin; xüsusi istifadə vəziyyətiniz bunlardan hansını dəstəkləmək istədiyinizi müəyyənləşdirməyə kömək edəcəkdir.
Other Bindings
Libgit2 bir çox dildə bağlanır.
Bu yazıdan etibarən daha dolğun bağlama paketlərindən bir neçəsini istifadə edərək kiçik bir nümunə göstərdik; kitabxanalar C++, Go, Node.js, Erlang, və JVM, daxil olmaqla bir çox başqa dillər üçün mövcuddur.
Rəsmi bağlamalar kolleksiyasını https://github.com/libgit2 saytındakı depolara baxmaqla tapa bilərsiniz.
Yazacağımız kod HEAD tərəfindən göstərilən commit-in öhdəsindən gələn mesajı qaytaracaqdır (git log -1
kimi).
LibGit2Sharp
Bir .NET və ya Mono tətbiqi yazırsınızsa, LibGit2Sharp (https://github.com/libgit2/libgit2sharp) axtardığınız şeydir. Bağlamalar C# -də yazılıb və xam Libgit2 zənglərini doğma hiss olunan CLR API-lərlə bağlamağa çox diqqət yetirilib. Nümunə proqramımız belə görünür:
new Repository(@"C:\path\to\repo").Head.Tip.Message;
Masaüstü Windows tətbiqetmələrində, işə başlamağınıza kömək edəcək bir NuGet paketi də var.
objective-git
Tətbiqiniz bir Apple platformasında işləyirsə, ehtimal ki, tətbiq dili olaraq Objective-C istifadə edirsiniz. Obyektiv-Git (https://github.com/libgit2/objective-git) bu mühit üçün Libgit2 bağlamalarının adıdır. Nümunə proqram belə görünür:
GTRepository *repo =
[[GTRepository alloc] initWithURL:[NSURL fileURLWithPath: @"/path/to/repo"] error:NULL];
NSString *msg = [[[repo headReferenceWithError:NULL] resolvedTarget] message];
Objective-git Swift ilə tam qarşılıqlı əlaqəlidir, buna görə də Objective-C-ni geridə qoymusunuzsa qorxmayın.
pygit2
Pythondakı Libgit2 üçün bağlamalara Pygit2 deyilir və https://www.pygit2.org-də tapa bilərsiniz. Nümunə proqramımız:
pygit2.Repository("/path/to/repo") # open repository
.head # get the current branch
.peel(pygit2.Commit) # walk down to the commit
.message # read the message
Əlavə Oxu
Əlbətdə ki, Libgit2-nin imkanlarına tam bir baxış bu kitabın əhatəsi xaricindədir. Libgit2’nin özü haqqında daha çox məlumat istəyirsinizsə, https://libgit2.github.com/libgit2 ünvanında API sənədləri və https://libgit2.github.com/docs adresində bir sıra təlimatlar var.
Digər bağlamalar üçün birləşdirilmiş README və testləri yoxlayın; tez-tez orada daha da oxumaq üçün kiçik təlimatlar və göstəricilər var.