Uzak Git deposundan belirli işlemleri alma


189

Uzak bir Git deposundan bilgisayarımda klonlamadan yalnızca belirli bir işlem almanın herhangi bir yolu var mı? Uzak repo'nun yapısı kesinlikle benimkiyle aynıdır ve bu nedenle herhangi bir çatışma olmayacaktır, ancak bunu nasıl yapacağım hakkında hiçbir fikrim yok ve bu büyük depoyu klonlamak istemiyorum.

Git için yeniyim, bir yolu var mı?


1
Mevcut deponuz zaten uzaktaki bir klon mu, yoksa tamamen farklı mı?
CharlesB

Depo Linux çekirdeği kaynağı ve hemen hemen aynı
Varun Chitre

yani bir klon mu yoksa hayır mı?
CharlesB

1
Tam olarak değil. Bunu düşünün, uzaktan repo D başında olsun ve benimki A başında ve B, C, D tarafından geride kaldı. Bu depolardaki B, C, D taahhütlerinin kendi uzmanlıklarından farklı olduğu için B'yi bir repo ve C'yi diğerinden ve D'yi diğerinden birleştirmek istiyorum
Varun Chitre

1
@VarunChitre VonC tarafından verilen diğer yanıtı kabul edebilir misiniz?
CharlesB

Yanıtlar:


109

Git sürüm 2.5+ (Q2 2015) ile başlayarak, tek bir taahhüt (tam repoyu klonlamadan) getirmek aslında mümkündür.

Bkz 68ee628 taahhüt tarafından Fredrik Medley ( moroten) , 21 Mayıs 2015
(tarafından Birleştirilmiş Junio C Hamano - gitster- içinde a9d3493 işlemek 2015 Haziran 1)

Artık yeni bir yapılandırmanız var (sunucu tarafında)

uploadpack.allowReachableSHA1InWant

upload-packHerhangi bir ref ipucundan erişilebilen bir nesne isteyen bir getirme isteğinin kabul edilmesine izin ver . Ancak, nesne erişilebilirliğinin hesaplanmasının hesaplama açısından pahalı olduğunu unutmayın.
Varsayılan olarak false.

Bu sunucu tarafı yapılandırmasını sığ bir klonla ( git fetch --depth=1) birleştirirseniz, tek bir işlem gerçekleştirebilirsiniz (bkz t/t5516-fetch-push.sh:

git fetch --depth=1 ../testrepo/.git $SHA1

git cat-fileKomutun getirildiğini görmek için komutu kullanabilirsiniz :

git cat-file commit $SHA1

" git upload-pack" hizmet eder " git fetch", bir uploadpack.allowReachableSHA1InWant yapılandırma değişkeniyle bir ref'den erişilebildiği sürece herhangi bir ref'nin ucunda olmayan taahhütleri sunması söylenebilir .


Belgelerin tamamı:

upload-pack: isteğe bağlı olarak ulaşılabilir sha1 getirilmesine izin ver

İle uploadpack.allowReachableSHA1InWantsunucu tarafında yapılandırma seçeneği seti, " git fetchisimleri reklamı olmayan bir nesnenin (muhtemelen müzik grubuna veya bir alt modül pointer dışarı elde edilmiş) olduğu Talep" hat "a sahip bir istek yapabilirsiniz".
Yalnızca şube ipuçlarından erişilebilen nesneler, yani reklamı yapılan şube ve tarafından gizlenen şube birliği transfer.hideRefsişlenecektir.
Okunabilirliği kontrol etmek için geçmişe geri dönmenin bir maliyeti olduğunu unutmayın.

Bu özellik, sha1'in bilindiği belirli bir taahhüdün içeriğini elde ederken, özellikle sığ bir getirme kullanılıyorsa, tüm deponun klonlanmasına gerek kalmadan kullanılabilir .

Yararlı durumlar örn.

  • tarihte büyük dosyalar içeren depolar,
  • bir alt modül ödemesi için yalnızca gerekli verileri getirme,
  • bir sha1'i hangi tam dalağa ait olduğunu ve Gerrit'te olduğunu söylemeden paylaşırken, değişiklik sayıları yerine taahhütler açısından düşünürseniz.
    (Gerrit davası, allowTipSHA1InWanther Gerrit değişikliğinin bir referansı olduğu için zaten çözülmüştür .)

Git 2.6 (2015 3. Çeyrek) bu modeli geliştirecektir.
Bkz. Taahhüt 2bc31d1 , taahhüt cc118a6 (28 Temmuz 2015), Jeff King ( peff) .
(Göre Birleştirilmiş - Junio Cı Hamano gitster- içinde 824a0be tamamlama 2015 19 Eyl)

refs: negatif desteği transfer.hideRefs

Bir refs hiyerarşisini transfer.hideRefsconfig kullanarak gizlerseniz , daha sonra bu yapılandırmayı "göster" için geçersiz kılmanın bir yolu yoktur.
Bu düzeltme eki, başka bir eşleşme gizlese bile eşleşmelerin hemen gizlenmemiş olarak işaretlenmesine neden olan "negatif" bir gizleme uygular.
Eşleşmeleri, yapılandırma makineleri tarafından bize nasıl beslendiklerinden ters sırada uygulamaya özen gösteriyoruz, çünkü her zamanki "sonuncusu kazanır" yapılandırma önceliği çalışmamıza izin verir (ve .git/configörneğin, girişler geçersiz kılar /etc/gitconfig).

Böylece artık şunları yapabilirsiniz:

git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'

refs/secretBelirli bir repodaki bir genel bit dışında, tüm depolarda gizlemek için.


Git 2.7 (Kasım / Aralık 2015) tekrar gelişecek:

Bkz 948bfa2 işlemek , 00b293e taahhüt , (2015 05 Kas) 78a766a işlemek , 92cab49 taahhüt , 92cab49 taahhüt , 92cab49 taahhüt (2015 3 Kasım), 00b293e taahhüt , 00b293e taahhüt (2015 05 Kas) ve 92cab49 taahhüt , 92cab49 taahhüt , 92cab49 taahhüt , Lukas Fleischer ( ) tarafından 92cab49 (03 Kasım 2015) taahhüt edildi . Yardım eden: Eric Sunshine ( ) . (Tarafından Birleştirilmiş Jeff Kral - - in dbba85e işlemek , 20 Kasım 2015)lfos
sunshineco
peff

config.txt: hideRefsad alanlarıyla anlambilimini belgelemek

Şu anda, transfer.hideRefsbir ad alanı ayarlandığında nasıl davranması gerektiği konusunda net bir tanım yoktur . Bu durumda öneklerin soyulmuş isimlerle eşleştiğini
açıklayın hideRefs. hideRefsDesenlerin şu anda alma paketinde nasıl işlendiği.

hideRefs: tam referansları eşleştirmek için destek ekleyin

Sökülen ref'lerin eşleştirilmesine ek olarak, artık hideRefstam (sökülmemiş) ref'nin eşleştiği desenler eklenebilir .
Soyulmuş ve tam eşleşmeleri birbirinden ayırmak için, bu yeni kalıpların önüne circumflex ( ^) eklenmelidir .

Dolayısıyla yeni belgeler :

transfer.hideRefs:

Bir ad alanı kullanılıyorsa, ad alanı öneki, transfer.hiderefskalıplarla eşleştirilmeden önce her bir referanstan çıkarılır .
Örneğin, refs/heads/masterbelirtilen transfer.hideRefsve geçerli isim olup foo, daha sonra refs/namespaces/foo/refs/heads/master ilanlarından atlanırsa ama refs/heads/masterve refs/namespaces/bar/refs/heads/masteryine de sözde "var" çizgiler olarak gösterilmektedir.
Sıyırma işleminden önce referansları eşleştirmek ^için ref adının önüne bir ekleyin . Eğer birleştirirseniz !ve ^, !önce belirtmeniz gerekir.


R. , yorumlarda , herhangi bir nesneyi isteyen bir isteği kabul etmeyi uploadpack.allowAnySHA1InWantsağlayan yapılandırmadan bahseder . (Varsayılan olarak ).upload-packfetchfalse

Bkz f8edeaa taahhüt tarafından (Kasım 2016, Git v2.11.1) David "novalis" Turner ( novalis) :

upload-pack: isteğe bağlı olarak herhangi bir sha1 getirilmesine izin ver

Kullanıcının depodaki her şeye kesinlikle erişmesine güvendiğimiz durumda bir yeniden kontrol kontrolü yapmak biraz aptalca görünüyor.

Ayrıca, dağıtılmış bir sistemde açıktır - belki bir sunucu bir ref reklamını yapar, ancak diğeri o zamandan beri bu ref'ye zorladı ve belki de iki HTTP isteği bu farklı sunuculara yönlendirildi.


4
Sadece bu tek taahhütle repo klonunun nasıl oluşturulacağına dair daha eksiksiz bir örnek verebilir misiniz? Denedim ama başarısız oldum .. Teşekkürler!
Lars Bilke

1
GitHub'a zorlamak istiyorum. Belki buna izin vermezler.
Lars Bilke

2
@LarsBilke klondan bahsediyoruz ya da buraya çekin, itmeyin. Ve GitHub'ın henüz sunucu tarafında Git 2.5'e sahip olmadığından eminim.
VonC

2
Daha da iyisi, uploadpack.allowAnySHA1InWantulaşılabilirlik hesaplama cezası (ve DoS vektörü) yok.
R .. GitHub BUZA YARDIMCI DURDUR

1
Teşekkürler! Bunu "repo yazarlarına halka açmayı düşünmedikleri rastgele saçmalıklara itmemeleri için güvenmek" yerine "erişim için kullanıcıya güven" olarak tanımlamaları komik buluyorum.
R .. GitHub BUZA YARDIMCI DURDUR

98

Sadece bir kez klonlarsınız, bu yüzden zaten uzak depodan bir klonunuz varsa, ondan çekmek her şeyi tekrar indirmez. Sadece hangi kolu çekmek istediğinizi belirtin veya değişiklikleri getirin ve istediğiniz taahhüdü kontrol edin.

Yeni bir depodan alma, bant genişliğinde çok ucuzdur, çünkü yalnızca sahip olmadığınız değişiklikleri indirecektir. Minimum yük ile Git'i doğru yapmayı düşünün.

Git her şeyi .gitklasörde saklar . Bir taahhüt alınamaz ve tek başına saklanamaz, tüm atalarına ihtiyacı vardır. Bunlar birbiriyle ilişkilidir .


Bununla birlikte, indirme boyutunu azaltmak için git'ten yalnızca belirli bir dal veya taahhüdle ilgili nesneleri getirmesini isteyebilirsiniz:

git fetch origin refs/heads/branch:refs/remotes/origin/branch

Bu, yalnızca uzak dalda bulunan taahhütleri branch (ve yalnızca özlediklerinizi) indirir ve depolar origin/branch. Daha sonra birleştirebilir veya ödeme yapabilirsiniz.

Ayrıca yalnızca bir SHA1 taahhüdü belirtebilirsiniz:

git fetch origin 96de5297df870:refs/remotes/origin/foo-commit

Bu yalnızca belirtilen SHA-1 96de5297df870 (ve kaçırdığınız atalarını) taahhüdünü indirir ve (var olmayan) uzak dal olarak saklar origin/foo-commit.


3
Görünüşe göre klonun ne anlama geldiği konusunda kafa karışıklığı var. Uzak bir repodaki değişiklikleri getirdiğinizde onu kopyalamazsınız, sadece geçmişinizdeki taahhütleri alırsınız. Sonra hangi taahhüdü kontrol etmek istediğinizi seçin veya geçmişinizde birleştirin
CharlesB

1
Hala git getirme ile birçok veri (430mb) indirir. Gerekli taahhüt sadece birkaç kb'dir. Bunu gerçekten yapmak için özel bir komut yok mu? Peki 'git fetched' deposunu kaldırmak istersem ne olur? nerede saklanıyor?
Varun Chitre

9
Bu artık güncel değil. Biz gerçekleştirmek kapasitesine sahipler sığ klon , yanı sıra tek işlemek getir . Sığ klonların artık projenin tüm geçmişini bilmek zorunda kalmadan normal olarak itmesine ve getirmesine izin verildi, bu nedenle artık bir taahhüdün ataları olmadan tek başına var olamayacağını söylemek doğru değil. İlk klondan sonra getirme hakkında söyledikleriniz çok doğru, ancak daha ucuz seçeneklerimiz de var.
Theodore Murdock

6
Son komut (SHA1 taahhüdünü kullanarak) benim için çalışmıyor. Komut bir süre sessizce "bir şey" yapar ve sonra hiçbir mesaj veya görünür yan etkisi olmadan çıkar.
HRJ

1
@HRJ Evet, Git ile Ubuntu 16.04'te de karşılaştım 2.7.4-0ubuntu1.3. Bununla birlikte, 2.16.2-0ppa1~ubuntu16.04.1git-core PPA'dan kullanırken, bu olması gerektiği gibi çalışır. Düzeltilen bir hata gibi geliyor. Hızlı arama ile buna referans bulunamadı. Birisi bana bu konuda bir işaretçi getirebilirse, bu düzeltmeyi geri almak isterim.
gertvdijk

62

Git depomda bir çekiş yaptım:

git pull --rebase <repo> <branch>

Git'in şube için tüm kodları çekmesine izin verdim ve sonra ilgimi çeken taahhüde sıfırlama yapmaya gittim.

git reset --hard <commit-hash>

Bu yardımcı olur umarım.


1
Cevapların hiçbiri işe yaramadı, buna rağmen hayatımı kurtardı! Çok teşekkürler!
michaeltintiuc

Sıfırlama - sert klonlamadan sonra benim için çalıştı! Teşekkürler.
Nick-ACNB

3
-1: git reset --hardgenel çözümlerde paylaşıldığında, insanları yok eden tuzaklara yol açabilir (veya bu durumda: verilerini geri almanın önemsiz olduğu bir durumda).
yaauie

54

Tek bir uzak repo taahhüdünü

git fetch <repo> <commit>

nerede,

  • <repo>Uzak repo adı (örn olabilir origin(örn) ve hatta uzak bir repo URL https://git.foo.com/myrepo.git)
  • <commit> SHA1 taahhüdü olabilir

Örneğin

git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545

Taahhüdü (ve eksik ataları) getirdikten sonra,

git checkout FETCH_HEAD

Bunun sizi "bağımsız kafa" durumuna getireceğini unutmayın.


10
fetchOrada yaptığınız gibi belirli bir devir denediğimde git hata kodu 1 ile başarısız ve çıkış yok. Bu geçmiş sürümlerde kullanılan bir şey miydi? (Ben v2.0.2.)
Jack O'Connor

2
Düzenleme: Ben zaten bir tam yaptım gibi, yerel olarak taahhüt varsa zaten çalışır fetch, ancak bu durumda kullanımın ne olduğundan emin değilim.
Jack O'Connor

2
Gerçekten de bu git git 2.0.2 ile benim için artık işe yaramıyor gibi görünüyor. :(
Flow

2
git checkout FETCH_HEADyardım eder.
lzl124631x

1
Bu yöntem sığ getirme ile çalışmaz (örneğin --depth=1)!
kingmakerking

16

Uzak depoyu aşağıdakilerle getirebilirsiniz:

git fetch <repo>

nerede,

  • <repo>Uzak repo adı (örn olabilir origin(örn) ve hatta uzak bir repo URL https://git.foo.com/myrepo.git)

Örneğin:

git fetch https://git.foo.com/myrepo.git 

depoları getirdikten sonra istediğiniz taahhütleri birleştirebilirsiniz (soru bir taahhüdü almakla ilgili olduğu için, birleştirmek sadece bir taahhüt seçmek için kiraz toplama kullanabilirsiniz):

git merge <commit>
  • <commit> SHA1 taahhüdü olabilir

Örneğin:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

veya

git merge 0a071603d87e0b89738599c160583a19a6d95545

birleştirmek istediğiniz en son taahhüt ise FETCH_HEAD değişkenini de kullanabilirsiniz:

git cherry-pick (or merge) FETCH_HEAD

Bu, bir makinede Git hesabı kurulumu gerektirir. Test hesabı altında çalışmaz. Test hesabı altında çalışan bir şeyiniz var mı?
jww

ne demek istedin ? git getirmeyi yapamaz mısın?
Sérgio

Ummm yani komut git config set uploadpack.allowReachableSHA1InWant ?
Alexander Mills

2

Bu en iyi şekilde çalışır:

git fetch origin specific_commit
git checkout -b temp FETCH_HEAD

ne olursa olsun "temp" adını ... bu şube yetim olabilir


1.8.x
sorin

1

Sonunda git cherry-pick kullanarak belirli taahhüt klonlamak için bir yol buldum . Yerelde havuzunuz olmadığını ve uzaktan kumandadan belirli bir taahhütte bulunduğunuzu varsayarsak,

1) Local ve Git init'te boş depo oluşturmak

2) git uzaktan ekleme kaynağı " url-of-repository "

3) git fetch origin [birleştirilmedikçe dosyalarınızı yerel çalışma alanınıza taşımaz]

4) git cherry-pick " İhtiyacınız olan Enter-long-taahhüt-hash-hash "

Bu şekilde, yalnızca bu özel dosyadaki dosyalar yerelde yapılır.

Enter-uzun taahhüt karması:

Bunu -> git log --pretty = oneline kullanarak alabilirsiniz



0

İstenen işlem uzak repo'nun çekme isteklerinde ise, bunu kimliğiyle alabilirsiniz:

# Add the remote repo path, let's call it 'upstream':
git remote add upstream https://github.com/repo/project.git

# checkout the pull ID, for example ID '60':
git fetch upstream pull/60/head && git checkout FETCH_HEAD
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.