Yalnızca Git deposunun bir alt dizinini nasıl klonlayabilirim?


1409

Git havuzumda kökte iki alt dizin var:

/finisht
/static

Bu iken SVN , /finishtsüre, tek bir yerde teslim edildi /staticşöyle, başka bir yerde teslim edildi:

svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static

Git ile bunu yapmanın bir yolu var mı?



1
Bir 2014 kullanıcı için, ne git clonebasit komut ?? Ben kullanılan bu basit bir cevap . Daha basit bir şey varsa, lütfen yorum yapın
Peter Krauss

Deponun içeriğini klonlamaya çalışanlar için (kök klasörü oluşturmadan), bu çok kolay bir çözümdür: stackoverflow.com/questions/6224626/…
Marc

@JoachimBreitner: Bu soru Git'teki alt dizinleri kontrol etmekle (ki bu kolay), bu soru Git'teki alt dizinleri klonlamakla ilgilidir (ki bu imkansızdır).
Jörg W Mittag

@NickSergeant: 3 hafta önce piyasaya sürülen Git 2.19'dan itibaren, bu yanıtta görülebileceği gibi, nihayet mümkün: stackoverflow.com/a/52269934/2988 Bunu şimdi kabul etmeyi düşünün. Not: Git 2.19'da yalnızca istemci tarafı desteği uygulanmıştır, sunucu tarafı desteği hala yoktur, bu nedenle yalnızca yerel depoları klonlarken çalışır. Ayrıca GitHub gibi büyük Git sunucularının aslında Git sunucusunu kullanmadığını, kendi uygulamalarını kullandıklarını unutmayın, bu nedenle Git sunucusunda destek görünse bile, otomatik olarak Git sunucularında çalıştığı anlamına gelmez. (OTOH, daha hızlı uygulayabilirler.)
Jörg W Mittag

Yanıtlar:


612

EDIT : Git 2.19 itibariyle, bu cevapta görülebileceği gibi, nihayet mümkün .

Bu cevabı iptal etmeyi düşünün.

Not: Git 2.19'da yalnızca istemci tarafı desteği uygulanır, sunucu tarafı desteği hala eksiktir, bu nedenle yalnızca yerel depoları klonlarken çalışır. Ayrıca, GitHub gibi büyük Git sunucularının aslında Git sunucusunu kullanmadığını, kendi uygulamalarını kullandıklarını unutmayın, bu nedenle Git sunucusunda destek görünse bile, otomatik olarak Git sunucularında çalıştığı anlamına gelmez. (OTOH, Git sunucusunu kullanmadığından, Git sunucusunda görünmeden önce kendi uygulamalarında daha hızlı uygulayabilirler.)


Hayır, Git'te bu mümkün değil.

Git'te böyle bir şey uygulamak önemli bir çaba olacaktır ve bu, müşteri tarafındaki veri havuzunun bütünlüğünün artık garanti edilemeyeceği anlamına gelir. Eğer ilgileniyorsanız, git posta listesindeki "seyrek klon" ve "seyrek getirme" ile ilgili tartışmalar arayın.

Genel olarak, Git topluluğundaki fikir birliği, her zaman bağımsız olarak kontrol edilen birkaç dizininiz varsa, bunlar gerçekten iki farklı projedir ve iki farklı depoda yaşamalıdır. Git Submodules kullanarak bunları tekrar yapıştırabilirsiniz .


6
Senaryoya bağlı olarak, git alt modülü yerine git alt ağacını kullanmak isteyebilirsiniz. Bkz. Alumnit.ca/~apenwarr/log/?m=200904#30
C Korsan

9
@StijndeWitt: Seyrek check-out'lar git-read-treeuzun süre sonra gerçekleşiyor get-fetch. Soru sadece bir alt dizini kontrol etmek değil, sadece bir alt dizini klonlamakla ilgiliydi . git-read-treeKlon zaten tamamlandıktan sonra çalıştığından , seyrek check-out'ların bunu nasıl yapabileceğini görmüyorum .
Jörg W Mittag

9
Bu "saplama" dan ziyade, Chronial'ın zirveye çıkabilmesi için bu cevabı silmemi ister misiniz? Bunu kendiniz silemezsiniz, çünkü kabul edilir, ancak bir moderatör bunu yapabilir. Çok eski olduğu için kazandığınız itibarı koruyacaksınız. (Birisi "sadece bağlantı" olarak işaretledi çünkü ben bu rastladım. :-)
Cody Gray

1
@CodyGray: Kronik cevap hala sadece bir alt dizini değil , tüm depoyu klonlar . (Son paragraf açıkça söylüyor bile.) Git'te yalnızca bir alt dizini kopyalamak mümkün değildir . Ağ protokolü desteklemiyor, depolama biçimi desteklemiyor. Bu sorunun her cevabı her zaman tüm depoyu klonlar. Soru basit bir Evet / Hayır sorusudur ve cevap iki karakterdir: Hayır. Cevabım gereksiz yere uzun , kısa değil.
Jörg W Mittag

1
@ JörgWMittag: Ciro Santili'nin cevabı sizinle çelişiyor gibi görünüyor.
Dan Dascalescu

1524

Yapmaya çalıştığınız seyrek kontrol olarak adlandırılır ve bu özellik git 1.7.0'da (Şubat 2012) eklenmiştir. Seyrek bir klon yapmak için adımlar aşağıdaki gibidir:

mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>

Bu, uzaktan kumandanızla boş bir havuz oluşturur ve tüm nesneleri getirir, ancak teslim almaz. Sonra şunları yapın:

git config core.sparseCheckout true

Şimdi hangi dosyalara / klasörlere gerçekten göz atmak istediğinizi tanımlamanız gerekir. Bu, bunları listeleyerek yapılır .git/info/sparse-checkout, örneğin:

echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout

Son olarak, boş deponuzu uzaktan kumandadaki durumla güncelleyin:

git pull origin master

Artık dosya sisteminiz için some/dirve another/sub/treesisteminizde (bu yollar hala devam ederken) "teslim alınmış" dosyalarınız olacak ve başka bir yol bulunmayacak.

Genişletilmiş eğiticiye göz atmak isteyebilirsiniz ve muhtemelen seyrek ödeme için resmi belgeleri okumalısınız .

İşlev olarak:

function git_sparse_clone() (
  rurl="$1" localdir="$2" && shift 2

  mkdir -p "$localdir"
  cd "$localdir"

  git init
  git remote add -f origin "$rurl"

  git config core.sparseCheckout true

  # Loops over remaining args
  for i; do
    echo "$i" >> .git/info/sparse-checkout
  done

  git pull origin master
)

Kullanımı:

git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"

Bu işlemin tüm deposu sunucudan indirmeye devam edeceğini unutmayın - yalnızca kasa boyutu küçültülür. Şu anda yalnızca tek bir dizini klonlamak mümkün değildir. Ancak deponun geçmişine ihtiyacınız yoksa, en azından sığ bir klon oluşturarak bant genişliğinden tasarruf edebilirsiniz. Görmek udondan yanıtını sığ birleştirmek hakkında bilgi için aşağıdaki klon ve seyrek ödeme.


Git 2.25.0 (Ocak 2020) itibariyle git'e deneysel seyrek ödeme komutu eklendi:

git sparse-checkout init
# same as: 
git config core.sparseCheckout true

git sparse-checkout set "A/B"
# same as:
echo "A/B" >> .git/info/sparse-checkout

git sparse-checkout list
# same as:
cat .git/info/sparse-checkout

14
Apple'da '-f' çevresi çalışmıyor. -f olmadan sadece uzak git kökeni ekle <url>
Anno2001

135
Bu bir gelişmedir, ancak yine de uzak havuzun tam bir kopyasını indirip depolaması gerekir; bu, yalnızca kod tabanının bölümleriyle ilgileniyorsa (ya da benim durumumda olduğu gibi belge alt klasörleri varsa) kaçınmak isteyebilir. )
a1an

56
İstediğim dizin içeriğini (dizinin kendisini değil) depoya kopyalamanın bir yolu var mı? Örneğin https://github.com/Umkus/nginx-boilerplate/tree/master/srcsağ içine klon içeriğini istiyorum/etc/nginx
mac

25
@Chronial, @ErikE: P: Doğru / yanlış ikisisinde git remote addkomutu gelmez değil bir getirme ima ama git remote add -fburada kullanıldığı gibi, yapar! Bunun -fanlamı budur.
ntc2

21
--depth=1Bunu kullanarak Chromium Devtools'u 4.9 GB tam Blink kaynağı + geçmişi yerine 338 MB'da klonladım. Mükemmel.
Rudie

444

git clone --filter Git 2.19'dan

Bu seçenek aslında gereksiz nesneleri sunucudan getirmeyi atlar. Ayrıca --filter=tree:0Git 2.20 ve Git 2.24'e--filter=combine eklenen bileşik filtre de dahil olmak üzere :

git clone \
  --depth 1 \
  --filter=combine:blob:none+tree:0 \
  --no-checkout \
  "file://$(pwd)/server_repo" \
  local_repo \
;
cd local_repo
git checkout master -- mydir/

Sunucu aşağıdakilerle yapılandırılmalıdır:

git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1

Git uzak protokolüne, bu özelliği desteklemek v2.19.0ve aslında gereksiz nesnelerin getirilmesini atlamak için bir uzantı yapıldı , ancak şu anda sunucu desteği yok. Ancak zaten yerel olarak test edilebilir.

Komut dökümü:

Biçimi --filterbelgelenmiştir man git-rev-list.

Git ağacındaki dokümanlar:

Test edin

#!/usr/bin/env bash
set -eu

list-objects() (
  git rev-list --all --objects
  echo "master commit SHA: $(git log -1 --format="%H")"
  echo "mybranch commit SHA: $(git log -1 --format="%H")"
  git ls-tree master
  git ls-tree mybranch | grep mybranch
  git ls-tree master~ | grep root
)

# Reproducibility.
export GIT_COMMITTER_NAME='a'
export GIT_COMMITTER_EMAIL='a'
export GIT_AUTHOR_NAME='a'
export GIT_AUTHOR_EMAIL='a'
export GIT_COMMITTER_DATE='2000-01-01T00:00:00+0000'
export GIT_AUTHOR_DATE='2000-01-01T00:00:00+0000'

rm -rf server_repo local_repo
mkdir server_repo
cd server_repo

# Create repo.
git init --quiet
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1

# First commit.
# Directories present in all branches.
mkdir d1 d2
printf 'd1/a' > ./d1/a
printf 'd1/b' > ./d1/b
printf 'd2/a' > ./d2/a
printf 'd2/b' > ./d2/b
# Present only in root.
mkdir 'root'
printf 'root' > ./root/root
git add .
git commit -m 'root' --quiet

# Second commit only on master.
git rm --quiet -r ./root
mkdir 'master'
printf 'master' > ./master/master
git add .
git commit -m 'master commit' --quiet

# Second commit only on mybranch.
git checkout -b mybranch --quiet master~
git rm --quiet -r ./root
mkdir 'mybranch'
printf 'mybranch' > ./mybranch/mybranch
git add .
git commit -m 'mybranch commit' --quiet

echo "# List and identify all objects"
list-objects
echo

# Restore master.
git checkout --quiet master
cd ..

# Clone. Don't checkout for now, only .git/ dir.
git clone --depth 1 --quiet --no-checkout --filter=blob:none "file://$(pwd)/server_repo" local_repo
cd local_repo

# List missing objects from master.
echo "# Missing objects after --no-checkout"
git rev-list --all --quiet --objects --missing=print
echo

echo "# Git checkout fails without internet"
mv ../server_repo ../server_repo.off
! git checkout master
echo

echo "# Git checkout fetches the missing directory from internet"
mv ../server_repo.off ../server_repo
git checkout master -- d1/
echo

echo "# Missing objects after checking out d1"
git rev-list --all --quiet --objects --missing=print

GitHub akış yukarı .

Git v2.19.0'daki çıktı:

# List and identify all objects
c6fcdfaf2b1462f809aecdad83a186eeec00f9c1
fc5e97944480982cfc180a6d6634699921ee63ec
7251a83be9a03161acde7b71a8fda9be19f47128
62d67bce3c672fe2b9065f372726a11e57bade7e
b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1
308150e8fddde043f3dbbb8573abb6af1df96e63 d1/a
f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 d1/b
84de03c312dc741d0f2a66df7b2f168d823e122a d2
0975df9b39e23c15f63db194df7f45c76528bccb d2/a
41484c13520fcbb6e7243a26fdb1fc9405c08520 d2/b
7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master
8b25206ff90e9432f6f1a8600f87a7bd695a24af master/master
ef29f15c9a7c5417944cc09711b6a9ee51b01d89
19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch
1b671b190e293aa091239b8b5e8c149411d00523 mybranch/mybranch
c3760bb1a0ece87cdbaf9a563c77a45e30a4e30e
a0234da53ec608b54813b4271fbf00ba5318b99f root
93ca1422a8da0a9effc465eccbcb17e23015542d root/root
master commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
mybranch commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
040000 tree b64bf435a3e54c5208a1b70b7bcb0fc627463a75    d1
040000 tree 84de03c312dc741d0f2a66df7b2f168d823e122a    d2
040000 tree 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3    master
040000 tree 19f7a4ca4a038aff89d803f017f76d2b66063043    mybranch
040000 tree a0234da53ec608b54813b4271fbf00ba5318b99f    root

# Missing objects after --no-checkout
?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
?308150e8fddde043f3dbbb8573abb6af1df96e63

# Git checkout fails without internet
fatal: '/home/ciro/bak/git/test-git-web-interface/other-test-repos/partial-clone.tmp/server_repo' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

# Git checkout fetches the missing directory from internet
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.

# Missing objects after checking out d1
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb

Sonuç: dışından tüm lekeler d1/eksik. Örneğin 0975df9b39e23c15f63db194df7f45c76528bccb, d2/bkontrol ettikten sonra orada değil d1/a.

Ayrıca root/rootve mybranch/mybrancheksik olduğunu unutmayın , ancak --depth 1eksik dosyalar listesinden gizler. Kaldırırsanız --depth 1, eksik dosyalar listesinde gösterilirler.

bir hayalim var

Bu özellik Git'te devrim yaratabilir.

Kuruluşunuzun tüm kod tabanının, çirkin üçüncü taraf araçları olmadan tek bir repoda olduğunu düşününrepo .

Çirkin üçüncü taraf uzantıları olmadan büyük lekeleri doğrudan depoda sakladığınızı düşünün .

GitHub'ın yıldız ve izinler gibi her dosya / dizin meta verilerine izin verip vermeyeceğini hayal edin , böylece tüm kişisel öğelerinizi tek bir repo altında saklayabilirsiniz.

Düşünün altmodüller aynen normal dizinler gibi tedavi edildi : sadece bir ağaç SHA'yı talep ve DNS benzeri mekanizma isteğinizi giderir öncelikle bakarak, yerel~/.git daha sonra ilk yakın sunucuları (şirketinizin ayna / önbellek) için, ve GitHub üzerinde biten.


İşin garibi, git sürüm 2.20.1 (Apple Git-117) bulunan
macOS'ta

1
Ne yazık ki, macOS git sürümünde şans yok. fatal: invalid filter-spec 'combine:blob:none+tree:0'Yine de teşekkürler! Belki daha yeni sürümlerle çalışacaktır.
muru

1
GIT 2.24.1 kullanarak Windows 10 üzerinde denediğinizde bu başarısız olur (ton "" sha1 dosyası okunamıyor .. "+" xxx dosyasının bağlantısı kaldırılamadı.). Linux'ta aynı sürümde bir cazibe olarak çalıştı.
Oyvind

1
@Ciro Santilli Git 2.26.1.windows.1 sürümündeki "... sha1 dosyası okunamıyor" ile hala başarısız oluyor. Bir hata raporu açtım: github.com/git-for-windows/git/issues/2590
nharrer

1
@nharrer bilgi için teşekkürler!
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功

405

Birleştirebilirsiniz seyrek ödeme ve sığ klon özellikleri. Sığ klon tarihi ve kapalı kesimler seyrek kasada sadece modellerle eşleşen dosyaları çeker.

git init <repo>
cd <repo>
git remote add origin <url>
git config core.sparsecheckout true
echo "finisht/*" >> .git/info/sparse-checkout
git pull --depth=1 origin master

Bunun çalışması için minimum git 1.9'a ihtiyacınız olacak. Sadece 2.2.0 ve 2.2.2 ile test ettim.

Bu şekilde hala zorlayabilirsiniz , ki bu mümkün değildir git archive.


21
Bu yararlıdır ve mevcut en iyi cevap olabilir, ancak yine de umursadığınız içeriği (çektiğiniz dalda ise), kasada görünmese bile klonlar .
nobar

1
Git sürümünüz nedir? Git yardımına göre derinlik seçeneği mevcut mu?
udondan

2
son komut olmadığında benim için çalışmıyor git pull --depth=1 origin masterama git pull --depth=1 origin <any-other-branch>. bu çok garip, soruma buradan bakın :stackoverflow.com/questions/35820630/…
Shuman

5
Windows'ta, ikinci-son satırın tırnak işaretlerini atlaması gerekir veya çekme başarısız olur.
nateirvin

4
Bu yine de tüm verileri indirir! Svn kullanarak bu çözümü buldum: stackoverflow.com/a/18324458/2302437
electronix384128

157

Sadece github'dan bir dosya / klasör indirmek isteyen diğer kullanıcılar için şunları kullanın:

svn export <repo>/trunk/<folder>

Örneğin

svn export https://github.com/lodash/lodash.com/trunk/docs

(evet, bu svn burada. görünüşe göre 2016'da hala bazı github dosyalarını indirmek için svn'ye ihtiyacınız var)

Nezaket: GitHub deposundan tek bir klasör veya dizin indirin

Önemli - github URL'sini güncellediğinizden ve değiştirdiğinizden emin olun/tree/master/ '/ trunk /' ile .

Bh betiği olarak:

git-download(){
    folder=${@/tree\/master/trunk}
    folder=${folder/blob\/master/trunk}
    svn export $folder
}

Not Bu yöntem bir klasörü indirir, klonlamaz / teslim almaz. Değişiklikleri depoya geri gönderemezsiniz. Öte yandan - bu, seyrek ödeme veya sığ ödeme ile karşılaştırıldığında daha küçük indirme ile sonuçlanır.


9
github ile benim için çalışan tek sürüm. Git komutları> 10k dosyaları teslim aldı, svn sadece istediğim 700 ihracat. Teşekkürler!
Christopher Lörken

4
Bunu yapmaya çalıştım https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacityama svn: E170000: URL 'https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/trunk/udacity' doesn't existhata aldım :(
zthomas.nc

9
@ zthomas.nc Udacity'den önceki 'trunk' u kaldırmanız ve bunun yerine / tree / master / yerine / trunk / yazmanız gerekir.
Speedy

2
Bu komut benim için çalışan buydu! Yerel olarak değiştirebilmem için bir dosyanın bir kopyasından bir kopyasını almak istedim. Kurtarmak için iyi eski SVN!
Michael J

3
çalışıyor, ancak yavaş görünüyor. başlamak için biraz zaman alır ve sonra dosyalar nispeten yavaş yavaş yuvarlanıyor
Aryeh Beitz

73

Klonladığınız havuzla asla etkileşimde bulunmayı planlamıyorsanız, tam git klonunu yapabilir ve git filter-branch --subdirectory-filter kullanarak deponuzu yeniden yazabilirsiniz . Bu şekilde, en azından tarih korunacaktır.


11
Komutu bilmeyen insanlar için, bugit filter-branch --subdirectory-filter <subdirectory>
Jaime Hablutzel

9
Bu yöntem, seçtiğiniz alt dizinin yeni havuzun kökü haline gelmesi avantajına sahiptir, ki bu tam olarak istediğim şeydir.
Andrew Schulman

Bu defenitly kullanmak için en iyi ve en kolay yaklaşım. git clone https://github.com/your/repo_xx.git && cd repo_xx && git filter-branch --subdirectory-filter repo_xx_subdir
Alex

66

Bu çok daha basit görünüyor:

git archive --remote=<repo_url> <branch> <path> | tar xvf -

17
Bunu github'da yaptığımda ölümcül oluyorum: İşlem protokol tarafından desteklenmiyor. Komut akışının beklenmedik sonu
Michael Fox

1
Protokol hatası HTTPS veya repo url'sinde olabilir. Ayrıca ssh anahtarı eksik olabilir.
Umair A.7

2
Eğer github kullanıyorsanız svn exportbunun yerine kullanabilirsiniz
Milo Wielondek

2
Github ile çalışmaz -> Geçersiz komut: 'git-upload-archive' xxx / yyy.git '' Bir git: // URL'yi klonlamak için ssh kullanıyor gibi görünüyorsunuz. Core.gitProxy yapılandırma seçeneğinizin ve GIT_PROXY_COMMAND ortam değişkeninin ayarlanmadığından emin olun. ölümcül: Uzak uç beklenmedik bir şekilde telefonu kapattı
Nianliang

3
Bunun GitHub ile çalışmadığının nedeni: "Bir arşivi doğrudan GitHub'dan çekmek için git-arşivinin kullanılmasını desteklemiyoruz. Repoyu yerel olarak klonlayabilir ve git-arşivini çalıştırabilir veya repo sayfası. " github.com/xuwupeng2000/capistrano-scm-gitcopy/issues/16
Donn Lee


37

Alt dizini yalnızca Git ile klonlamak mümkün değildir, ancak aşağıda birkaç geçici çözüm bulunmaktadır.

Filtre kolu

Depoyu trunk/public_html/, proje köküymiş gibi görünecek şekilde yeniden yazmak ve diğer tüm geçmişi (kullanarak filter-branch) silmek , zaten ödeme dalını deneyin:

git filter-branch --subdirectory-filter trunk/public_html -- --all

Notlar: --Filtre dalı seçeneklerini düzeltme seçeneklerinden ayıran ve --alltüm dalları ve etiketleri yeniden yazmak için. Orijinal işlem süreleri veya birleştirme bilgileri dahil tüm bilgiler korunacaktır . Bu komut, .git/info/graftsdosya ve refleri refs/replace/ad alanında onurlandırır , bu nedenle refstanımlı herhangi bir greft veya değiştirme varsa , bu komutu çalıştırmak onları kalıcı hale getirir.

Uyarı! Yeniden yazılan geçmiş, tüm nesneler için farklı nesne adlarına sahip olacak ve orijinal dalla birleşmeyecektir. Yeniden yazılan dalı orijinal dalın üstüne kolayca itemez ve dağıtamazsınız. Tam sonuçları bilmiyorsanız lütfen bu komutu kullanmayın ve sorununuzu çözmek için basit bir tek taahhüt yeterliyse yine de kullanmaktan kaçının.


Seyrek ödeme

İşte çalışma dizinini seyrek dolduracak seyrek ödeme yaklaşımı ile basit adımlar , böylece Git'e çalışma dizinindeki hangi klasörlerin veya dosyaların kontrol edilmeye değer olduğunu söyleyebilirsiniz.

  1. Her zamanki gibi klon deposu ( --no-checkoutisteğe bağlı):

    git clone --no-checkout git@foo/bar.git
    cd bar
    

    Deponuz zaten klonlanmışsa bu adımı atlayabilirsiniz.

    İpucu: Büyük depolar için, yalnızca en son revizyonu ve / veya yalnızca ödeme yapmak için sığ klonu ( --depth 1) düşünün --single-branch.

  2. Etkinleştir sparseCheckoutseçeneği:

    git config core.sparseCheckout true
    
  3. Seyrek ödeme için klasör (ler) belirtin ( sonunda boşluk olmadan ):

    echo "trunk/public_html/*"> .git/info/sparse-checkout
    

    veya düzenleyin .git/info/sparse-checkout.

  4. Şubeyi kontrol edin (örn. master):

    git checkout master
    

Şimdi geçerli dizininizde klasör seçmiş olmalısınız.

Bunun yerine çok fazla sayıda dizin veya filtreleme dalı varsa sembolik bağlantılar düşünebilirsiniz.



Misiniz Filtre dalı yine de izin pull?
sam

2
@sam: hayır. filter-branchüst taahhütleri yeniden yazacak, böylece farklı SHA1 kimlikleri olacaktır ve bu nedenle filtrelenmiş ağacınızın uzak ağaçla ortak hiçbir taahhütleri olmayacaktır. git pullnereden birleşmeye çalışılacağını bilmiyordu.
Peter Cordes

Bu yaklaşım benim durumum için çoğunlukla tatmin edici bir cevap.
Abbas

10

Sadece bir komut dosyası yazdım için GitHub'dan .

Kullanımı:

python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>

11
Bilginize, bu sadece GitHub içindir.
Sz.

9
Ve görünüşe göre bu bir dizini indirmek için, tüm meta verileri ile bir repo parçasını klonlamak değil ... değil mi?
LarsH

5
Kodunuzu buraya eklemelisiniz, başka bir yere değil.
jww

urllib2.HTTP Hata: HTTP Hatası 403: oran sınırı aşıldı
diyizm

9

Bu, belirli bir klasörü klonlar ve onunla ilgili olmayan tüm geçmişi kaldırır.

git clone --single-branch -b {branch} git@github.com:{user}/{repo}.git
git filter-branch --subdirectory-filter {path/to/folder} HEAD
git remote remove origin
git remote add origin git@github.com:{user}/{new-repo}.git
git push -u origin master

Burada ejderhalar olsun. Sen tarafından karşılandı olsun UYARI: git-filtre-dal parçalanmış tarih yeniden yazılma üreten Sorunlar bir fazlalığı vardır .. . Daha sonra git-filtre-şube belgelerinin oldukça uzun bir uyarı listesi vardır.
Oyvind

6

İşte tek bir alt dizin seyrek ödeme kullanımı için yazdım bir kabuk komut dosyası

coSubDir.sh

localRepo=$1
remoteRepo=$2
subDir=$3


# Create local repository for subdirectory checkout, make it hidden to avoid having to drill down to the subfolder
mkdir ./.$localRepo
cd ./.$localRepo
git init
git remote add -f origin $remoteRepo
git config core.sparseCheckout true

# Add the subdirectory of interest to the sparse checkout.
echo $subDir >> .git/info/sparse-checkout

git pull origin master

# Create convenience symlink to the subdirectory of interest
cd ..
ln -s ./.$localRepo/$subDir $localRepo

2
Güzel senaryo, sadece düzeltilmesi gereken bir şey sembolik, ln -s ./.$localRepo/$subDir $localRepoyerine olmalıdır ln -s ./.$localRepo$subDir $localRepo
valentin_nasta

2

Yazdım .gitconfig [alias]Bir "seyrek ödeme" yapmak için bir . Check it out (hiçbir cinas amaçlanan):

Windows'da çalıştırın cmd.exe

git config --global alias.sparse-checkout "!f(){ [ $# -eq 2 ] && L=${1##*/} L=${L%.git} || L=$2; mkdir -p \"$L/.git/info\" && cd \"$L\" && git init --template= && git remote add origin \"$1\" && git config core.sparseCheckout 1; [ $# -eq 2 ] && echo \"$2\" >> .git/info/sparse-checkout || { shift 2; for i; do echo $i >> .git/info/sparse-checkout; done }; git pull --depth 1 origin master;};f"

Aksi takdirde:

git config --global alias.sparse-checkout '!f(){ [ $# -eq 2 ] && L=${1##*/} L=${L%.git} || L=$2; mkdir -p "$L/.git/info" && cd "$L" && git init --template= && git remote add origin "$1" && git config core.sparseCheckout 1; [ $# -eq 2 ] && echo "$2" >> .git/info/sparse-checkout || { shift 2; for i; do echo $i >> .git/info/sparse-checkout; done }; git pull --depth 1 origin master;};f'

Kullanımı :

# Makes a directory ForStackExchange with Plug checked out
git sparse-checkout https://github.com/YenForYang/ForStackExchange Plug

# To do more than 1 directory, you have to specify the local directory:
git sparse-checkout https://github.com/YenForYang/ForStackExchange ForStackExchange Plug Folder

git configKomutlar kolaylık ve depolama için 'minified', ama burada genişletilmiş takma adıdır:

# Note the --template= is for disabling templates.
# Feel free to remove it if you don't have issues with them (like I did)
# `mkdir` makes the .git/info directory ahead of time, as I've found it missing sometimes for some reason
f(){
    [ "$#" -eq 2 ] && L="${1##*/}" L=${L%.git} || L=$2;
    mkdir -p "$L/.git/info"
        && cd "$L"
        && git init --template=
        && git remote add origin "$1"
        && git config core.sparseCheckout 1;
    [ "$#" -eq 2 ]
        && echo "$2" >> .git/info/sparse-checkout
        || {
            shift 2;
            for i; do
                echo $i >> .git/info/sparse-checkout;
            done
        };
    git pull --depth 1 origin master;
};
f

Neden çalışıyor L=${1##*/} L=${L%.git}? Alan bir operatör müdür?
Gulzt

2

Linux mu kullanıyorsunuz? Ve sadece çalışma ağacına erişmek ve temizlemek kolay mı istiyorsunuz? makinenizdeki kodun geri kalanını rahatsız etmeden. sembolik bağlantıları deneyin !

git clone https://github.com:{user}/{repo}.git ~/my-project
ln -s ~/my-project/my-subfolder ~/Desktop/my-subfolder

Ölçek

cd ~/Desktop/my-subfolder
git status

1

Buradaki harika cevaplardan bazılarını açıklığa kavuşturmak için, cevapların çoğunda özetlenen adımlar zaten bir yerde uzak bir deponuz olduğunu varsayar.

Verilen: mevcut bir git deposu, örneğin deponun geri kalanından bağımsızgit@github.com:some-user/full-repo.git olarak çekmek istediğiniz bir veya daha fazla dizinle , örneğin veapp1app2

Yukarıdaki gibi bir git deponuz olduğu varsayılarak ...

Ardından: bu daha büyük depodan yalnızca belirli dizinleri almak için aşağıdaki gibi adımları çalıştırabilirsiniz :

mkdir app1
cd app1
git init
git remote add origin git@github.com:some-user/full-repo.git
git config core.sparsecheckout true
echo "app1/" >> .git/info/sparse-checkout
git pull origin master

Yanlışlıkla, seyrek ödeme seçeneklerinin orijinal depoda ayarlanması gerektiğini düşündüm: durum böyle değil. Uzaktan kumandadan çekmeden önce yerel olarak hangi dizinleri istediğinizi tanımlarsınız. Umarım bu açıklama başka birine yardımcı olur.


0

Git depoları ile uğraşırken aslında svn kullanmak zorunda nefret ederken: / Ben her zaman bunu kullanın;

function git-scp() (
  URL="$1" && shift 1
  svn export ${URL/blob\/master/trunk}
)

Bu, değiştirmeden github url'sinden kopyalamanızı sağlar. Kullanımı;

--- /tmp » git-scp https://github.com/dgraph-io/dgraph/blob/master/contrib/config/kubernetes/helm                                                                                                                  1 ↵
A    helm
A    helm/Chart.yaml
A    helm/README.md
A    helm/values.yaml
Exported revision 6367.

--- /tmp » ls | grep helm
Permissions Size User    Date Modified    Name
drwxr-xr-x     - anthony 2020-01-07 15:53 helm/

0

Bir dizinin en son revizyon dosyalarıyla ilgileniyorsanız, Github, geçmişi içermeyen bir depoyu Zip dosyası olarak indirmenize izin verir. Yani indirmek çok daha hızlı.


0

Bu yüzden bu sırttaki her şeyi denedim ve hiçbir şey benim için işe yaramadı ... Git'in 2.24 sürümünde (bu cevap sırasında cpanel ile gelen) çıkıyor, bunu yapmanıza gerek yok

echo "wpm/*" >> .git/info/sparse-checkout

tek ihtiyacınız olan klasör adı

wpm/*

Kısacası bunu yapıyorsun

git config core.sparsecheckout true

daha sonra .git / info / sparse-checkout'u düzenler ve alt klasörleri ve dosyaları almak için sonuna / * ile klasör adlarını (her satıra bir tane) eklersiniz

wpm/*

Ödeme komutunu kaydedin ve çalıştırın

git checkout master

Sonuç benim repo beklenen klasör oldu ve başka bir şey Bu sizin için çalıştı olsaydı Olumlu oy

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.