Có thể thực hiện kiểm tra thưa thớt mà không kiểm tra toàn bộ kho lưu trữ trước không?


170

Tôi đang làm việc với một kho lưu trữ với số lượng tệp rất lớn, phải mất hàng giờ để thanh toán. Tôi đang xem xét khả năng Git có hoạt động tốt với loại kho lưu trữ này hay không khi nó hỗ trợ kiểm tra thưa thớt nhưng mọi ví dụ mà tôi có thể tìm thấy đều làm như sau:

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

Vấn đề với chuỗi lệnh này là bản sao gốc cũng thực hiện kiểm tra. Nếu bạn thêm -n vào lệnh clone gốc, thì lệnh đọc cây sẽ dẫn đến lỗi sau:

lỗi: Thanh toán thưa thớt không có mục trên thư mục làm việc

Làm thế nào có thể thực hiện kiểm tra thưa thớt mà không kiểm tra tất cả các tập tin đầu tiên?



Lưu ý: git worktree add --no-checkoutcũng sẽ hoạt động (không chỉ git clone --no-checkout) với git 2.9 (Chỉ 2016). Xem câu trả lời của tôi dưới đây
VonC

Sau khi thử tất cả các giải pháp ở đây, cách duy nhất để tải xuống thư mục (không cần đẩy sau đó!) Là đây .
LondonRob

Câu trả lời:


23

Vào năm 2020, có một cách đơn giản hơn để đối phó với thanh toán thưa thớt mà không phải lo lắng về các tệp .git. Đây là cách tôi đã làm nó:

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

Lưu ý rằng nó yêu cầu git phiên bản 2.25 được cài đặt. Đọc thêm về nó ở đây: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-spude-checkout/

CẬP NHẬT:

Lệnh trên git clonevẫn sẽ sao chép repo với lịch sử đầy đủ của nó, mặc dù không kiểm tra các tệp. Nếu bạn không cần lịch sử đầy đủ, bạn có thể thêm tham số --depth vào lệnh, như sau:

# create a shallow clone,
# with only 1 (since depth equals 1) latest commit in history
git clone <URL> --no-checkout <directory> --depth 1

1
Đó là sự thật, điểm tốt. Nâng cao. Tôi đã làm theo sparse-checkout --conetính năng trong stackoverflow.com/a/59515426/6309
VonC

Sẽ có giá trị khi thêm một phần clone ( --filter) vào câu trả lời của bạn ở đây.
Tao

@ alexey-grinko, lệnh đầu tiên vẫn phải sao chép toàn bộ repo trong câu hỏi, ngay cả khi nó không kiểm tra nó ... Tôi đang tìm cách tiết kiệm thời gian không nhân bản tất cả những thứ tôi không cần .. .
mropp

1
@mropp, tôi đã cập nhật câu trả lời bằng cách thêm --depththam số cho phép chúng tôi thực hiện một bản sao nông. Điều đó sẽ giúp chứ? @Tao, không chắc cách sử dụng --filtertrong trường hợp này, tôi đã không thử. Bạn có thể cung cấp một ví dụ, hoặc đăng một câu trả lời khác cho chủ đề này?
Alexey Grinko

3
lưu ý rằng nó không hoạt động giống nhau trong phiên bản 2.27 - Tôi không biết tại sao.
Blazes

162

Xin lưu ý rằng câu trả lời này không tải xuống một bản sao hoàn chỉnh của dữ liệu từ kho lưu trữ. Các git remote add -flệnh sẽ sao chép toàn bộ kho lưu trữ. Từ trang người đàn ông củagit-remote :

Với -ftùy chọn, git fetch <name>được chạy ngay sau khi thông tin từ xa được thiết lập.


Thử cái này:

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

Bây giờ bạn sẽ thấy rằng bạn có một kiểm tra "được cắt tỉa" chỉ với các tệp từ đường dẫn / trong vòng numpo / đến / wish_subdir hiện tại (và trong đường dẫn đó).

Lưu ý rằng trên dòng lệnh windows, bạn không được trích dẫn đường dẫn, tức là bạn phải thay đổi lệnh thứ 6 bằng lệnh này:

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

nếu bạn không nhận được dấu ngoặc kép trong tệp thanh toán thưa thớt và nó sẽ không hoạt động


3
Tôi không thể sử dụng lệnh "git checkout [Branchname]" (cũng tìm thấy lỗi: Thanh toán thưa thớt không để lại mục nào trong thư mục làm việc). Tôi đã sử dụng "git pull origin master" và nó hoạt động đúng.
Natty

2
Với git phiên bản 1.7.2.5 trên linux, tôi có kết quả như sau: echo 'dir / *' để kiểm tra chỉ các tập tin trong thư mục / nhưng không phải trong subdirs của nó; echo 'dir /' (không có dấu sao!) kiểm tra chính xác toàn bộ cây theo dir /. HTH
pavek

37
Điều này hoàn toàn không phù hợp với tôi - lệnh "git remote" dẫn đến toàn bộ repo đã được kiểm tra - bam! - ngay lúc đó; vì vậy "git config ..." và đặc tả của một thư mục con quan tâm trong các lệnh sau không có hiệu lực. URL repo được chỉ định trong lệnh "git remote" có phải là đường dẫn đến tệp .git cấp cao nhất không? Hoặc nó nên là một đường dẫn đến thư mục con quan tâm?
Rob Cranfill

10
đây là phiên bản được sắp xếp hợp lý (không cần tạo thư mục thủ công, thực hiện init và thêm từ xa, chỉ cần thực hiện chu trình git clone + thanh toán bình thường với tùy chọn --no-checkout như được đề cập bởi @onionjake): git clone --no-checkout <project> cd <project> echo <dir >> .git / thông tin / thưa thớt kiểm tra git checkout <chi nhánh>
Gregor

22
Các git remote addlệnh tải tất cả mọi thứ vì đó là những gì -fkhông - nói với nó ngay lập tức lấy, trước khi bạn đã xác định các tùy chọn thanh toán thưa thớt. Nhưng bỏ qua hoặc sắp xếp lại sẽ không có ích. Kiểm tra thưa thớt chỉ ảnh hưởng đến cây làm việc, không phải kho lưu trữ. Nếu bạn muốn kho lưu trữ của bạn thực hiện chế độ ăn kiêng thay thế, thì bạn cần phải xem --depthhoặc --single-branchcác tùy chọn thay thế.
Miral

43

Git clone có một tùy chọn ( --no-checkouthoặc -n) thực hiện những gì bạn muốn.

Trong danh sách các lệnh của bạn, chỉ cần thay đổi:

git clone <path>

Về điều này:

git clone --no-checkout <path>

Sau đó, bạn có thể sử dụng kiểm tra thưa thớt như được nêu trong câu hỏi.


7
vâng, nó không thực hiện kiểm tra, nhưng vẫn tìm cách tải xuống toàn bộ lịch sử repo
Jason S

9
@JasonS câu hỏi cụ thể là về việc không thanh toán. Nếu bạn không muốn thì toàn bộ lịch sử sử dụng --depth <depth>tùy chọn trên git clone. Điều đó sẽ chỉ tải xuống các <depth>cam kết cuối cùng từ lịch sử. Hiện tại không có cách nào để tải xuống một phần một cam kết với git, mặc dù nếu điều khiển từ xa của bạn hỗ trợ, bạn có thể sử dụng git archive --remoteđể tải xuống một phần các tập tin.
tây

Bây giờ bạn cũng có thể 'kiểm tra' một cam kết mà không cần tải xuống bất kỳ tệp nào bằng vfsforgit.org . Điều này có thể hữu ích nếu ai đó đang cố gắng chỉ kiểm tra một tập hợp con nhỏ của một cam kết duy nhất.
tây

22

Tôi đã có một trường hợp sử dụng tương tự, ngoại trừ tôi chỉ muốn kiểm tra cam kết cho một thẻ và cắt tỉa các thư mục. Sử dụng --depth 1làm cho nó thực sự thưa thớt và thực sự có thể tăng tốc mọi thứ.

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>

3
--depth 1 được gọi là bản sao nông, chỉ là FYI.
Đánh dấu Allison

1
Điều này đã giúp! Cảm ơn bạn
kp123

1
Cảm ơn vì điều đó. Hoàn toàn đúng với điều này sau khi thử nhiều cách khác để ngăn tải xuống toàn bộ repo.
J ... S

12

Tôi đã tìm thấy câu trả lời mà tôi đang tìm kiếm từ một bài đăng được đăng trước đó bởi pavek (cảm ơn!) Vì vậy tôi muốn cung cấp một câu trả lời hoàn chỉnh trong một câu trả lời duy nhất hoạt động trên 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

Tôi đã thay đổi thứ tự của các lệnh một chút nhưng điều đó dường như không có bất kỳ tác động nào. Chìa khóa là sự hiện diện của dấu gạch chéo "/" ở cuối đường dẫn trong bước 5.


3
bạn có chắc đây là thứ bạn muốn không? -f có nghĩa là tìm nạp tất cả dữ liệu, bạn vẫn nhận được tất cả thông tin khác mà bạn không muốn và nó chậm. (Đây vẫn là "kiểm tra toàn bộ kho lưu trữ")
Shuman

1
Tôi đã thử các bước trên trong Windows nhưng kiểm tra dự phòng không hoạt động trong dấu nhắc lệnh nên tôi đã thử trình vỏ Git Bash và nó đã hoạt động !!. dấu nhắc lệnh có thể thực thi tất cả các lệnh git như đẩy, kéo, v.v. nhưng khi kiểm tra thưa thớt thì thất bại.
dùng593029

Làm thế nào để chỉ làm các tập tin của thư mục con. Tôi muốn chỉ tìm nạp các tập tin trong thư mục con cụ thể.
Babish Shrestha

@BabishShrestha xem bình luận của hành tây trên câu trả lời khác FWIW: |
rogerdpack

9

Đáng buồn thay, không có cách nào ở trên làm việc cho tôi vì vậy tôi đã dành rất nhiều thời gian để thử kết hợp khác nhau sparse-checkout tập tin .

Trong trường hợp của tôi, tôi muốn bỏ qua các thư mục với cấu hình IntelliJ IDEA.

Đây là những gì tôi đã làm:


Chạy git clone https://github.com/myaccount/myrepo.git --no-checkout

Chạy git config core.sparsecheckout true

Được tạo .git\info\sparse-checkoutvới nội dung sau

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

Chạy 'git checkout -' để lấy tất cả các tệp.


Điều quan trọng để làm cho nó hoạt động là thêm /* sau tên thư mục.

Tôi có git 1.9


3
Không, nó vẫn tải xuống mọi thứ, tất cả các cam kết và tất cả các tệp, git 2.3.2
Tyguy7

6
Kiểm tra thưa thớt chỉ ảnh hưởng đến cây làm việc. Chúng không ảnh hưởng đến kích thước kho lưu trữ hoặc những gì được tìm nạp. Bạn cần các tùy chọn khác nhau nếu bạn muốn điều đó.
Miral

Hãy thử Git Bash Shell vào lần tới nếu làm việc trong Windows và sử dụng các bước trên của 'pbetkier', nó hoạt động tốt
user593029

6

Có, Có thể tải xuống một thư mục thay vì tải xuống toàn bộ kho lưu trữ. Ngay cả bất kỳ / cam kết cuối cùng

Cách tốt để làm điều này

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -r ĐẦU sẽ chỉ tải xuống bản sửa đổi cuối cùng, bỏ qua tất cả lịch sử.

  2. Lưu ý thân cây và / thư mục cụ thể

Sao chép và thay đổi URL trước và sau /trunk/. Tôi hy vọng điều này sẽ giúp được ai đó. Thưởng thức :)

Cập nhật vào ngày 26 tháng 9 năm 2019


chỉ áp dụng cho những người đến từ hoặc sử dụng svn. Sẽ không upvote này.
C Johnson

@CJohnson như bạn thấy, tôi đang nhân bản thư mục git repo. Hoạt động tốt
Qamar

1
Lưu ý rằng đây không phải là thứ mà git cung cấp ngoài hộp mà là thứ mà trung tâm Git cung cấp liền kề với ưu đãi Git thông thường. Tuy nhiên, nó hoạt động rất đẹp khi bạn có thể sử dụng nó. Cảm ơn!
Qix - MONICA ĐƯỢC PHÂN PHỐI

1
Trong số vô số lời đề nghị về SO, bạn là giải pháp ngắn gọn và rõ ràng nhất.
boardrider

4

git 2.9 (tháng 6 năm 2016) sẽ tổng quát hóa --no-checkouttùy chọn git worktree add(lệnh cho phép hoạt động với nhiều cây làm việc cho một repo )

Xem cam kết ef2a0ac (29 tháng 3 năm 2016) của Ray Zhang ( OneRaynyDay) .
Được giúp đỡ: Eric Sunshine (sunshineco )Junio ​​C Hamano ( gitster) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 0d8683c , ngày 13 tháng 4 năm 2016)

Các git worktreetrang người đàn ông hiện nay bao gồm:

--[no-]checkout:

Theo mặc định, add để kiểm tra <branch>, tuy nhiên, --no-checkoutcó thể được sử dụng để kiểm tra đàn áp để thực hiện các tùy chỉnh, chẳng hạn như cấu hình thưa thớt-thanh toán .


4

Các bước để kiểm tra thưa thớt chỉ thư mục cụ thể:

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]

FYI, trong bước đầu tiên (1), bạn không cần sử dụng - không thanh toán. Chỉ cần sao chép toàn bộ repo và sau đó thực hiện tất cả các bước dưới đây 2-5 (đã đề cập ở trên), bạn sẽ nhận được đầu ra những gì bạn muốn. Hãy cho tôi biết nếu bạn không nhận được nó.
SANDEEP MachIRAJU

4

Dựa trên câu trả lời này của apenwarrnhận xét này của Miral, tôi đã đưa ra giải pháp sau đây giúp tôi tiết kiệm gần 94% dung lượng đĩa khi sao chép kho lưu trữ linux git cục bộ trong khi chỉ muốn một thư mục con Tài liệu:

$ 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    .

Vì vậy, tôi đã giảm từ 2.9GB xuống còn 182 MB, nó khá yên tĩnh.

Mặc dù tôi đã không làm cho nó hoạt động với git clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test( gợi ý ở đây ) vì sau đó tất cả các tệp bị thiếu đã được thêm dưới dạng các tệp đã xóa vào chỉ mục. Vì vậy, nếu bất cứ ai biết tương đương git clone --filter=blob:nonevới git fetch, chúng ta có thể tiết kiệm thêm một vài megabyte. (Đọc trang người đàn ông git-rev-listcũng gợi ý rằng có một cái gì đó giống như --filter=sparse:path=…, nhưng tôi cũng không làm cho nó hoạt động.

(Tất cả đã thử với git 2.20.1 từ Debian Buster.)


1
Phản hồi thú vị. Nâng cao. Tôi cũng không biết --filter=sparse:path=….
VonC

3

Tôi mới sử dụng git nhưng có vẻ như nếu tôi thực hiện kiểm tra git cho mỗi thư mục thì nó hoạt động. Ngoài ra, tệp kiểm tra thưa thớt cần phải có dấu gạch chéo sau mỗi thư mục như được chỉ định. Ai đó có thêm kinh nghiệm xin vui lòng xác nhận rằng điều này sẽ làm việc.

Thật thú vị, nếu bạn kiểm tra một thư mục không có trong tệp kiểm tra thưa thớt thì dường như không có sự khác biệt. Chúng không xuất hiện trong trạng thái git và git read-tree -m -u HEAD không khiến nó bị xóa. git reset - không làm cho thư mục bị xóa. Bất cứ ai có kinh nghiệm quan tâm hơn để bình luận về những gì git nghĩ về các thư mục được kiểm tra nhưng không có trong tệp thanh toán thưa thớt?


0

Trong trường hợp của tôi, tôi muốn bỏ qua Podsthư mục khi nhân bản dự án. Tôi đã làm từng bước như dưới đây và nó làm việc cho tôi. Hy vọng nó giúp.

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

Ghi nhớ, Nếu bạn muốn bỏ qua nhiều thư mục, chỉ cần thêm nhiều dòng trong tệp thanh toán thưa thớt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.