2015-01-25 51 views
5

here'a baktım ama merak ettiğim şeyleri tam olarak anlayamadım: git push veya git pull, diğer tarafta hangi nesnelerin eksik olduğunu nasıl anlıyor?Git, depolar arasında hangi nesnelerin gönderilmesi gerektiğini nasıl belirler?

en aşağıdaki kaydedilmesini içeren bir depo var diyelim:

a -> e -> f -> g 
:

a -> b -> c -> d 

uzaktan (drefs/heads/master olduğunu, mektuplar SHA-1 kimlikleri için durmak), aksine, bu vardır

Git belgesine göre, uzaktan kumanda bize refs/heads/master'un g adresinde olduğunu söyler, ancak bu işlemi bilmediğimizden, aslında bize hiçbir şey söylemez. Eksik verileri anlamaya ne dersiniz?

Diğer yönde ise

belirtiliyor: “istemek” Bu noktada

getirme paketi süreci içinde olanı nesneleri bakar ve göndererek ihtiyacı nesneler ile yanıt ve sonra istediği SHA-1. ,'un sahip olduğu tüm nesneleri “sahip” ve sonra SHA-1 ile gönderir. Bu listenin sonunda, ihtiyacı olan verilerin packfile göndermeye başlamak için yükleme paketi işlemini başlatmak için “bitti” yazıyor:

bu uzak göndermek için hangi verileri belirlemek, ama gitmeyeceklerini nasıl açıklıyor

Bu etki, birçok nesnenin bulunduğu depolardaki performansı artırır mı? Aksi halde, metinde aslında ne anlama geliyor?


Görünüşe göre, veri aktarımının yönü, yöne bağlı olarak çok farklıdır (çekime karşı itme). Bu tasarım seçiminde karşılaşılan zorluklar neler ve nasıl oluyor ve belgede açıklamalarını nasıl anlarım?

cevap

10

Sihir kimliğindedir. Bir taahhüt kimliği birçok şeyden oluşur, ancak temel olarak bunun bir SHA-1 hash.

  • İçerik (her şey, sadece fark)
  • Yazar
  • tarihi
  • Giriş mesajı
  • Veli kimlikleri

Değişim bunlardan herhangi ve yeni bir oluşturmanız gerekir yeni bir kimlik ile işlemek. Üst kimliklerin dahil edildiğini unutmayın.

Bu, Git için ne ifade ediyor? Bu, "ABC123" i işlediğimi ve "ABC123" i işlediğimizi, eğer aynı içerik, aynı yazar, aynı tarih, aynı mesaj ve aynı ebeveynler ile aynı işi yaptığımızı bildiğimiz anlamına gelir. Bu ebeveynler aynı kimliğe sahipler, böylece aynı içerik, aynı yazar, aynı tarih, aynı mesaj, ve aynı ebeveynler. Ve bunun gibi. Kimlikler eşleşiyorsa, aynı geçmişe sahip olmalıdır, hatta daha aşağıya doğru kontrol etmeye gerek yoktur.Bu Git'in en güçlü yanlarından biri, tasarımına derinden dokundu ve Git'i onsuz anlayamazsın.

Çekme, bir getirme artı birleştirme işlemidir. git pull origin master, git fetch origin ve git merge master origin/master (veya --rebase ile rebase) 'dir. getirme A

remote @ http://example.com/project.git 

        F - G [bugfix] 
       /
A - B - C - D - E - J [master] 
        \ 
         H - I [feature] 

local 
origin = http://example.com/project.git 

        F - G [origin/bugfix] 
       /
A - B - C - D - E [origin/master] [master] 
  • [yerel] uzak Hey, hangi dallar var ... şuna benzer?
  • [uzak] Bende hata düzeltildi, G.
  • [local] Ayrıca G! Bitti. Başka?
  • [remote] I özelliği var. I
  • [local] Özelliğim yok ve ben yok.
  • [remote] Ben ebeveynim H'dir
  • [local] H'm yok, H'nin ailesi nedir?
  • [remote] H'nin sorumlusu J'dir.
  • [local] N'm yok J'nin ebeveynleri?
  • [remote] J'nin sorumlusu E.
  • [local] Elimde E var! Bana gönder J, H ve ben lütfen.
  • [uzak] Tamam, işte geliyorlar.
  • [yerel] , J, H ve I'yi repo'ya ekler ve ben'daki kökeni/özelliği koyar, başka neler var?
  • [uzaktan] Ben J.
  • [yerel] adresinden master var ben E'de master var, zaten J J. hamle köken/efendi beni gönderdi. Başka?
  • [remote] İşte böyle!
  • [yerel] Kthxbi böyle

Ve şimdi yerel bakışlar ... Sonra

local 
origin = http://example.com/project.git 

        F - G [origin/bugfix] 
       /
A - B - C - D - E [master] - J [origin/master] 
           \ 
           H - I [origin/feature] 

o çekme bitirmek için git merge master origin/master yapacak, hızlı ileri J.

için olacak

Bir itme benzerdir, ancak süreç tersine gider (lokal gönderiler uzaktan kumandaya geçer) ve sadece hızlı ileri sarılacaktır.

Pro Git refers to as "the dumb protocol" budur ve uzaktan kumandanız basit bir HTTP sunucusu olduğunda kullanılır. The Smart Protocol daha sık kullanılan, daha az konuşkan ve birçok optimizasyona sahip. Ama ya ne kadar verimli olabileceğini görebilirsiniz. Tüm tarihi anlatmaya gerek yok, sadece ortak bir ata bulana kadar 20 baytlık hash anahtarı göndermeleri gerekiyor.

İşte bazı kaynaklar ve daha fazla okuma.

+0

Cevabınız harika, teşekkür ederim! Eğer sakıncası yoksa, özellikle çok sayıda turdan kaçınmakla ilgileniyorum. Bu sadece hevesle gönderen bir mesele mi?50 kareye kadar (<1kb), ya da bir taahhüt biliniyorsa daha hızlı tespit edebilecek daha teorik, algoritmik bir mekanizma var mı? –

+1

Ayrıca, cevabınız için herhangi bir kaynakınız varsa, bunlar harika olur. Benim endişem daha çok "git benzeri bir senkronizasyon mekanizması" uyguluyordu, bu yüzden tamamen tatmin oldum, ancak "git git senkronizasyonunun ayrıntılı olarak nasıl uygulandığı" nı arayan gelecekteki bir okuyucu bunu takdir edebilir. –

+0

@SillyFreak Daha fazla ayrıntı için birkaç referans ekledim. Konuşma örneği kavramsal olarak nasıl öğrettiğimi, Pro Git'in ne dediğini ["The Dumb Protocol"] (http://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#The-Dumb- Protokol). Daha verimli bir örnek için ["Akıllı Protokol"] 'e (http://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#The-Smart-Protocol) göz atmak istersiniz. – Schwern