Apakah mungkin melakukan checkout jarang tanpa memeriksa seluruh repositori terlebih dahulu?

171

Saya bekerja dengan repositori dengan sejumlah besar file yang membutuhkan waktu berjam-jam untuk checkout. Saya sedang mencari kemungkinan apakah Git akan bekerja dengan baik dengan repositori jenis ini sekarang karena ia mendukung pemeriksaan jarang, tetapi setiap contoh yang dapat saya temukan lakukan sebagai berikut:

git clone <path>
git config core.sparsecheckout true
echo <dir> > .git/info/sparse-checkout
git read-tree -m -u HEAD

Masalah dengan urutan perintah ini adalah klon asli juga melakukan checkout. Jika Anda menambahkan -n ke perintah klon asli, maka perintah baca-pohon menghasilkan kesalahan berikut:

kesalahan: checkout Jarang meninggalkan entri di direktori kerja

Bagaimana cara melakukan checkout jarang tanpa memeriksa semua file terlebih dahulu?

dromodel
sumber
Catatan: git worktree add --no-checkoutakan bekerja juga (tidak adil git clone --no-checkout) dengan git 2.9 (Baru 2016). Lihat jawaban saya di bawah ini
VonC
Setelah mencoba semua solusi di sini, satu-satunya yang hanya mengunduh direktori (tidak mendorong setelah itu!) Adalah ini .
LondonRob

Jawaban:

24

Pada tahun 2020 ada cara yang lebih sederhana untuk berurusan dengan jarang-checkout tanpa harus khawatir tentang file git. Inilah cara saya melakukannya:

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

Perhatikan bahwa ini membutuhkan git versi 2.25 yang diinstal. Baca lebih lanjut di sini: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

MEMPERBARUI:

git clonePerintah di atas masih akan mengkloning repo dengan riwayat lengkapnya, meskipun tanpa memeriksa file. Jika Anda tidak memerlukan riwayat lengkap, Anda dapat menambahkan parameter --depth ke perintah, seperti ini:

# create a shallow clone,
# with only 1 (since depth equals 1) latest commit in history
git clone <URL> --no-checkout <directory> --depth 1
Alexey Grinko
sumber
1
Itu benar, poin bagus. Terpilih. Saya mengikuti sparse-checkout --conefitur di stackoverflow.com/a/59515426/6309
VonC
Layak menambahkan tiruan sebagian ( --filter) ke jawaban Anda di sini.
Tao
@ alexey-grinko, perintah pertama masih harus mengkloning seluruh repo yang bersangkutan, bahkan jika tidak memeriksanya ... Saya ingin menghemat waktu untuk tidak mengkloning semua hal yang tidak saya butuhkan .. .
mropp
1
@ropp, saya memperbarui jawabannya dengan menambahkan --depthparameter yang memungkinkan kita untuk melakukan klon yang dangkal. Akankah itu membantu? @ Tao, tidak yakin bagaimana menggunakannya --filterdalam kasus ini, saya tidak mencobanya. Bisakah Anda memberikan contoh, atau memposting jawaban lain untuk topik ini?
Alexey Grinko
4
perhatikan bahwa itu tidak berfungsi sama pada rilis 2.27 - Saya tidak tahu mengapa.
Blazes
162

Harap dicatat bahwa jawaban ini tidak mengunduh salinan data lengkap dari repositori. The git remote add -fperintah akan mengkloning seluruh repositori. Dari halaman manual darigit-remote :

Dengan -fopsi, git fetch <name>dijalankan segera setelah informasi jarak jauh diatur.


Coba ini:

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add -f origin git://...
echo "path/within_repo/to/desired_subdir/*" > .git/info/sparse-checkout
git checkout [branchname] # ex: master

Sekarang Anda akan menemukan bahwa Anda memiliki checkout "pangkas" dengan hanya file dari path / inside_repo / ke / diinginkan_subdir hadir (dan di jalur itu).

Perhatikan bahwa pada baris perintah windows Anda tidak boleh mengutip path, yaitu Anda harus mengubah perintah ke-6 dengan yang ini:

echo path/within_repo/to/desired_subdir/* > .git/info/sparse-checkout

jika tidak, Anda akan mendapatkan penawaran di file jarang-checkout, dan itu tidak akan berfungsi

apenwarr
sumber
3
Saya tidak dapat menggunakan perintah "git checkout [branchname]" (juga menemukan kesalahan: Sparse checkout tidak meninggalkan entri pada direktori kerja). Saya telah menggunakan "git pull origin master" dan itu berfungsi dengan baik.
Natty
2
Dengan git versi 1.7.2.5 di linux, saya mendapatkan hasil sebagai berikut: echo 'dir / *' hanya memeriksa file-file di dir / tetapi tidak di subdirnya; echo 'dir /' (no asterix!) dengan benar memeriksa seluruh pohon di bawah dir /. HTH
pavek
37
Ini hanya tidak berhasil bagi saya - perintah "git remote" mengakibatkan seluruh repo diperiksa - bam! - saat itu juga; jadi "git config ..." dan spesifikasi sub-dir yang menarik pada perintah berikut ini tidak berpengaruh. Apakah URL repo ditentukan dalam perintah "git remote" hanya jalur ke file .git tingkat atas? Atau haruskah itu jalan ke sub-dir yang menarik?
Rob Cranfill
10
inilah versi yang disederhanakan (tidak perlu membuat direktori secara manual, melakukan init dan remote add, cukup lakukan siklus git clone + checkout yang normal dengan opsi - no-checkout seperti yang disebutkan oleh @onionjake): git clone --no-checkout <project> cd <project> echo <dir>> .git / info / sparse-checkout git checkout <branch>
Gregor
22
The git remote adddownload perintah segala sesuatu karena itulah yang -fdilakukannya - mengatakan itu untuk segera mengambil, sebelum Anda mendefinisikan jarang pilihan checkout. Tetapi menghilangkan atau menata ulang itu tidak akan membantu. Checkout jarang mempengaruhi hanya pohon kerja, bukan repositori. Jika Anda ingin repositori melakukan diet sebagai gantinya, maka Anda perlu melihat opsi --depthatau --single-branchsebagai gantinya.
Miral
43

Git clone memiliki opsi ( --no-checkoutatau -n) yang melakukan apa yang Anda inginkan.

Dalam daftar perintah Anda, ubah saja:

git clone <path>

Untuk ini:

git clone --no-checkout <path>

Anda kemudian dapat menggunakan checkout jarang seperti yang dinyatakan dalam pertanyaan.

onionjake
sumber
7
ya, itu tidak melakukan checkout, tetapi masih mengambil fetch untuk mengunduh seluruh sejarah repo
Jason S
9
@JasonS pertanyaannya secara khusus tentang tidak melakukan checkout. Jika Anda tidak mau maka seluruh histori menggunakan --depth <depth>opsi pada git clone. Itu hanya akan mengunduh <depth>komitmen terakhir dari riwayat. Saat ini tidak ada cara untuk mengunduh sebagian komit tunggal dengan git, meskipun jika remote Anda mendukungnya, Anda dapat menggunakannya git archive --remoteuntuk mengunduh sebagian file.
onionjake
Anda sekarang juga dapat 'memeriksa' komit tanpa mengunduh file apa pun menggunakan vfsforgit.org . Ini mungkin berguna jika seseorang hanya mencoba checkout sebagian kecil komit tunggal.
onionjake
22

Saya memiliki kasus penggunaan yang sama, kecuali saya ingin checkout hanya komit untuk tag dan memangkas direktori. Menggunakan --depth 1membuatnya sangat jarang dan benar-benar dapat mempercepat.

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add origin <url>  # Note: no -f option
echo "path/within_repo/to/subdir/" > .git/info/sparse-checkout
git fetch --depth 1 origin tag <tagname>
git checkout <tagname>
sourcedelica
sumber
3
--depth 1 disebut clone dangkal, hanya FYI.
Mark Allison
1
Ini membantu! Terima kasih
kp123
1
Terima kasih untuk ini. Sudah benar dengan ini setelah mencoba banyak cara lain untuk mencegah mengunduh seluruh repo.
J ... S
12

Saya menemukan jawaban yang saya cari dari one-liner yang diposting sebelumnya oleh pavek (terima kasih!) Jadi saya ingin memberikan jawaban lengkap dalam satu jawaban yang bekerja di Linux (GIT 1.7.1):

1--> mkdir myrepo
2--> cd myrepo
3--> git init
4--> git config core.sparseCheckout true
5--> echo 'path/to/subdir/' > .git/info/sparse-checkout
6--> git remote add -f origin ssh://...
7--> git pull origin master

Saya mengubah urutan perintah tapi sepertinya tidak berdampak apa-apa. Kuncinya adalah keberadaan garis miring "/" di ujung jalan di langkah 5.

JF Bergeron
sumber
3
apakah kamu yakin ini yang kamu inginkan? -f artinya mengambil semua data, Anda masih mendapatkan semua informasi lain yang tidak Anda inginkan dan lambat. (Ini masih "memeriksa seluruh repositori")
Shuman
1
Saya mencoba langkah-langkah di atas di Windows tetapi checkout checkout tidak berfungsi di command prompt jadi saya mencoba Git Bash shell dan berhasil !! command prompt dapat menjalankan semua perintah git seperti push, pull dll tetapi ketika datang ke checkout jarang gagal.
user593029
Bagaimana melakukan hanya file-file dari subdirektori. Saya hanya ingin mengambil file di dalam sub direktori tertentu.
Babish Shrestha
@BabishShrestha lihat komentar oleh onionjake pada jawaban lain FWIW: |
rogerdpack
9

Sayangnya tidak ada yang di atas bekerja untuk saya, jadi saya menghabiskan waktu yang sangat lama mencoba berbagai kombinasi sparse-checkoutfile.

Dalam kasus saya, saya ingin melewatkan folder dengan konfigurasi IntelliJ IDEA.

Inilah yang saya lakukan:


Lari git clone https://github.com/myaccount/myrepo.git --no-checkout

Lari git config core.sparsecheckout true

Dibuat .git\info\sparse-checkoutdengan konten berikut

!.idea/*
!.idea_modules/*
/*

Jalankan 'git checkout -' untuk mendapatkan semua file.


Hal penting untuk membuatnya berfungsi adalah menambahkan /*nama setelah folder.

Saya punya git 1.9

ahli
sumber
3
Tidak, itu masih mengunduh semuanya, semua komit dan semua file, git 2.3.2
Tyguy7
6
Checkout yang jarang hanya mempengaruhi pohon yang berfungsi. Mereka tidak memengaruhi ukuran repositori atau apa yang didapat. Anda memerlukan opsi berbeda jika menginginkannya.
Miral
Coba Git Bash Shell lain kali jika bekerja di Windows & gunakan langkah-langkah di atas dengan 'pbetkier' berfungsi dengan baik
user593029
6

Ya, Kemungkinan untuk mengunduh folder alih-alih mengunduh seluruh repositori. Bahkan ada / komit terakhir

Cara yang bagus untuk melakukan ini

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -R HEAD hanya akan mengunduh revisi terakhir, abaikan semua riwayat.

  2. Catatan trunk dan / folder spesifik

Salin dan ubah URL sebelum dan sesudah /trunk/. Saya harap ini akan membantu seseorang. Nikmati :)

Diperbarui pada 26 Sep 2019

Qamar
sumber
hanya berlaku untuk mereka yang datang dari atau menggunakan svn. Tidak akan mengungguli yang satu ini.
C Johnson
@ CJohnson seperti yang Anda lihat, saya kloning folder git repo. Bekerja dengan baik
Qamar
1
Perhatikan bahwa ini bukan sesuatu yang ditawarkan git di luar kotak, melainkan sesuatu yang ditawarkan hub Git yang berdekatan dengan penawaran Git biasa. Namun, ini berfungsi dengan baik ketika Anda dapat menggunakannya. Terima kasih!
Qix - MONICA DISEBUTKAN
1
Dari banyak sekali saran tentang SO, milik Anda adalah solusi yang paling ringkas dan jelas.
boardrider
5

Jawaban yang diperbarui 2020:

Sekarang ada perintah git sparse-checkout, yang saya presentasikan secara rinci dengan Git 2.25 (Q1 2020)

nicono 's jawaban menggambarkan penggunaannya:

git sparse-checkout init --cone # to fetch only root files
git sparse-checkout add apps/my_app
git sparse-checkout add libs/my_lib

Ini telah berevolusi dengan Git 2.27 dan tahu cara "mengajukan kembali" checkout yang jarang, seperti di sini .
Perhatikan bahwa dengan Git 2.28, Anda git statusakan disebutkan bahwa Anda berada dalam repositori yang jarang diperiksa

Jawaban asli: 2016

git 2.9 (Juni 2016) akan menggeneralisasi --no-checkoutopsi untuk git worktree add(perintah yang memungkinkan untuk bekerja dengan banyak pohon yang bekerja untuk satu repo )

Lihat komit ef2a0ac (29 Mar 2016) oleh Ray Zhang ( OneRaynyDay) .
Dibantu-oleh: Eric Sunshine ( sunshineco) , dan Junio ​​C Hamano ( gitster) .
(Digabung oleh Junio ​​C Hamano - gitster- dalam komit 0d8683c , 13 Apr 2016)

Itu git worktree halaman manual sekarang termasuk:

--[no-]checkout:

Secara default, addcheck out <branch>, bagaimanapun, --no-checkoutdapat digunakan untuk menekan checkout untuk membuat penyesuaian, seperti mengkonfigurasi checkout jarang .

VONC
sumber
4

Langkah-langkah untuk jarang checkout hanya folder tertentu:

1) git clone --no-checkout  <project clone url>  
2) cd <project folder>
3) git config core.sparsecheckout true   [You must do this]
4) echo "<path you want to sparce>/*" > .git/info/sparse-checkout
    [You must enter /* at the end of the path such that it will take all contents of that folder]
5) git checkout <branch name> [Ex: master]
SANDEEP MACHIRAJU
sumber
FYI, pada langkah (1) pertama, Anda tidak perlu menggunakan --no-checkout. Cukup kloning seluruh repo dan kemudian jalankan semua langkah di bawah 2-5 (disebutkan di atas), Anda akan mendapatkan output apa yang Anda inginkan. Beri tahu saya jika Anda tidak mendapatkannya.
SANDEEP MACHIRAJU
4

Berdasarkan jawaban ini oleh apenwarr dan komentar oleh Miral ini saya menemukan solusi berikut yang menyelamatkan saya hampir 94% dari ruang disk ketika mengkloning repositori linux git secara lokal sementara hanya menginginkan satu subdirektori Dokumentasi:

$ cd linux
$ du -sh .git .
2.1G    .git
894M    .
$ du -sh 
2.9G    .
$ mkdir ../linux-sparse-test
$ cd ../linux-sparse-test
$ git init
Initialized empty Git repository in /…/linux-sparse-test/.git/
$ git config core.sparseCheckout true
$ git remote add origin ../linux
# Parameter "origin master" saves a tiny bit if there are other branches
$ git fetch --depth=1 origin master
remote: Enumerating objects: 65839, done.
remote: Counting objects: 100% (65839/65839), done.
remote: Compressing objects: 100% (61140/61140), done.
remote: Total 65839 (delta 6202), reused 22590 (delta 3703)
Receiving objects: 100% (65839/65839), 173.09 MiB | 10.05 MiB/s, done.
Resolving deltas: 100% (6202/6202), done.
From ../linux
 * branch              master     -> FETCH_HEAD
 * [new branch]        master     -> origin/master
$ echo "Documentation/hid/*" > .git/info/sparse-checkout
$ git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
$ ls -l
total 4
drwxr-xr-x 3 abe abe 4096 May  3 14:12 Documentation/
$  du -sh .git .
181M    .git
100K    .
$  du -sh
182M    .

Jadi saya turun dari 2.9GB ke 182MB yang sudah cukup bagus.

Meskipun saya tidak mendapatkan ini untuk bekerja dengan git clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test( mengisyaratkan di sini ) karena kemudian file yang hilang semua ditambahkan sebagai file yang dihapus ke indeks. Jadi, jika ada yang tahu yang setara git clone --filter=blob:nonedengan git fetch, kita mungkin bisa menghemat lebih banyak megabita. (Membaca halaman manual git-rev-listjuga mengisyaratkan bahwa ada sesuatu seperti--filter=sparse:path=… , tetapi saya juga tidak berhasil.

(Semua mencoba dengan git 2.20.1 dari Debian Buster.)

Axel Beckert
sumber
1
Umpan balik yang menarik. Terpilih. Saya juga tidak tahu --filter=sparse:path=….
VonC
3

Saya baru mengenal git tetapi tampaknya jika saya melakukan checkout git untuk setiap direktori maka ia bekerja. Juga, file sparse-checkout perlu memiliki garis miring setelah setiap direktori seperti yang ditunjukkan. Seseorang yang lebih berpengalaman, harap pastikan bahwa ini akan berhasil

Menariknya, jika Anda checkout direktori yang tidak ada dalam file checkout jarang tampaknya tidak ada bedanya. Mereka tidak muncul dalam status git dan git read-tree -m -u HEAD tidak menyebabkannya dihapus. git reset --hard juga tidak menyebabkan direktori dihapus. Adakah yang lebih berpengalaman peduli untuk mengomentari pendapat git tentang direktori yang diperiksa tetapi yang tidak ada dalam file checkout yang jarang?

dromodel
sumber
1

Di git 2.27, sepertinya checkout git jarang telah berkembang. Solusi dalam hal ini jawabannya tidak bekerja dengan cara yang sama (dibandingkan dengan git 2,25)

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

Perintah-perintah ini bekerja lebih baik:

git clone --sparse <URL> <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout add apps/my_app
git sparse-checkout add libs/my_lib

Lihat juga: tambahkan git-clone --sparse dan git-sparse-checkout

nicono
sumber
1
Pembaruan bagus. Terpilih. Saya telah mengedit jawaban saya sendiri sesuai dengan itu. Saya telah mempresentasikan perintah itu pada Desember 2019: stackoverflow.com/a/59515426/6309
VonC
0

Dalam kasus saya, saya ingin melewati Podsfolder ketika kloning proyek. Saya melakukan langkah demi langkah seperti di bawah ini dan itu berhasil untuk saya. Semoga ini bisa membantu.

mkdir my_folder
cd my_folder
git init
git remote add origin -f <URL>
git config core.sparseCheckout true 
echo '!Pods/*\n/*' > .git/info/sparse-checkout
git pull origin master

Memo, Jika Anda ingin melewati lebih banyak folder, tambahkan saja lebih banyak baris dalam file jarang-checkout.

panjang eric
sumber