Làm thế nào để kéo thư mục cụ thể với git


193

Tôi có một dự án với git và tôi chỉ muốn sao chép hoặc kéo một thư mục cụ thể, như myproject / javascript giống như subversion.
thực hiện một số thay đổi, cam kết và đẩy lùi một lần nữa.
Có thể không?


3
thanh toán thưa thớt có thể khiến bạn quan tâm (mặc dù bạn vẫn cần tìm nạp mọi thứ): xem stackoverflow.com/questions/2416815/iêu
VonC

Câu trả lời:


205
  1. cd vào đầu bản sao repo của bạn
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • Trong trường hợp " path/..." trong (3) bắt đầu từ thư mục ngay dưới gốc repo chứa của bạn " .../file"

    • LƯU Ý rằng thay vì "CHÍNH", mã băm của một cam kết cụ thể có thể được sử dụng, và sau đó bạn sẽ nhận được sửa đổi (tệp) hoặc sửa đổi (dir) cụ thể cho cam kết đó.


1
Chỉ nhận ra tôi đã hiểu nhầm câu hỏi. Thay vào đó, câu trả lời của tôi giải quyết cách kiểm tra một tệp duy nhất, sau đó có thể được sửa đổi và cam kết.
vergueishon

Bạn đã giải quyết tiêu đề của câu hỏi, đó là đủ tốt. Điều này chỉ giúp tôi tiết kiệm, theo như tôi quan tâm, đây là câu trả lời chính xác - đặc biệt vì đây là một điểm nhấn hàng đầu trên Google cho vấn đề này.
Morgon

21
Điều này vẫn nhận được toàn bộ repo mặc dù. Đối với dự án có dung lượng 2GB, điều này không tiết kiệm nhiều thời gian ..
Pithikos

5
Đối với những người đọc những bình luận này và không biết làm thế nào điều này không trả lời câu hỏi, giải pháp này mang lại cho bạn một bản sao của chỉ một thư mục đó, nhưng nó không phải là một bản sao hoạt động, nghĩa là bạn không thể sửa đổi và làm lại -commit. Vì vậy, như @Morgon đã nói, nó giải quyết tiêu đề của câu hỏi (bạn chỉ có thể kéo một thư mục), nhưng không trả lời phần chính của câu hỏi ("thực hiện một số thay đổi, cam kết và đẩy lùi lại").
msb

@StanHolodnak --không bắt buộc. Nó buộc các bit sau khi nó được hiểu là một đường dẫn. Vì vậy, vâng, nếu bạn có một tệp có tên --helpmà bạn muốn thanh toán, thì cần phải thêm tiền tố vào các dấu gạch nối này:git checkout HEAD -- --help
Tim Visée

105

Trong một thư mục trống:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory

điều này hoạt động nếu bạn chỉ muốn sử dụng phiên bản từ xa của một tệp để thay thế tệp cục bộ, tôi nghĩ
John

Điều này cũng kéo thư mục, làm thế nào để không tải thư mục, nhưng chỉ những thứ bên trong thư mục?
Al Kasih

Không có bất kỳ nhu cầu fetchhoặc checkoutlệnh nào, chúng ta chỉ cần thực hiện yêu cầu kéo sau remote addlệnh để có được toàn bộ nhánh chính.
Iqra.

2
Như Pithkos chỉ ra trong câu trả lời được chấp nhận, câu trả lời này cũng sẽ tải xuống kho lưu trữ từ xa WHOLE về máy cục bộ của bạn. Câu trả lời của shingara là rõ ràng nhất - không có cách nào để kéo một phần của repo từ xa. Tuy nhiên, đối với những người không quan tâm đến băng thông của tìm nạp WHOLE và quan tâm đến việc tạo một bản sao hoạt động của một phần của bộ đệm cục bộ, thì câu trả lời được chấp nhận cho bạn thấy. Nhưng tôi chỉ muốn làm cho nó rõ ràng toàn bộ lịch sử của repo (ở định dạng nén) phải được tải xuống máy của bạn.
Gabe Halsmer

39

Sau khi tìm kiếm một câu trả lời, không tìm kiếm, từ bỏ, thử lại, tôi cuối cùng đã tìm ra giải pháp cho vấn đề này trong một chủ đề SO khác:

Làm thế nào để git-pull tất cả trừ một thư mục

Để sao chép-dán những gì có:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

Để làm những gì OP muốn (chỉ hoạt động trên một thư mục), chỉ cần thêm một thư mục đó vào .git/info/sparse-checkout, khi thực hiện các bước trên.

Rất cám ơn @cforbish!


2
Tôi đang đăng nó ở đây chủ yếu là vì bất cứ khi nào tôi cố gắng google làm thế nào để làm điều đó, đây là một kết quả hàng đầu và chủ đề đó thậm chí không được hiển thị. :( Tôi cảm thấy dán sao chép xấu, nhưng tôi nghĩ đó là cách thực hành tốt nhất?
msb

1
Đây là giải pháp sạch duy nhất. Đã thử các câu trả lời ở trên. Sau khi tôi kiểm tra chi nhánh của mình với các câu trả lời khác, tôi không thể kéo và có một số tệp mới cần cam kết. Với giải pháp này mọi thứ có vẻ đúng. Nhưng LƯU Ý: Bất kể chi nhánh nào đã được kiểm tra, git sẽ nghĩ bạn đang ở master. Chỉ cần chắc chắn rằng bạn làm git branch --set-upstream-to=origin/<branch>để kéo chính xác
seebcakes

12

Điều đó là không thể. Bạn cần kéo tất cả các kho lưu trữ hoặc không có gì.


1
Mặc dù bạn cần tìm nạp mọi thứ, nhưng liệu một cây kéo thanh toán thưa thớt có được quan tâm trong trường hợp này không? Xem stackoverflow.com/questions/2416815/iêu
VonC

10
Chỉ cần thêm vào điều này, lý do tại sao bạn không thể chỉ kéo một thư mục là vì git sử dụng theo dõi ngữ nghĩa dữ liệu, không phải theo dõi ngữ nghĩa tệp, do đó bạn có thể di chuyển liền mạch mã (hoặc dữ liệu khác) vào trong tệp mà không cần phải nói nguồn hệ thống theo dõi (cho đến khi bạn cập nhật tất nhiên.) Vì điều này, mã cũng có thể di chuyển vào và ra khỏi các thư mục một cách liền mạch, do đó, việc lấy chỉ một thư mục sẽ không có ý nghĩa nhiều. Hi vọng điêu nay co ich.
Toàn năngEntity

12
@OmnipotentEntity Xin lỗi nhưng IMHO nó ý nghĩa. Việc thực hiện không nên giới hạn việc sử dụng. Git không biết thư mục là gì (ít nhất là khi tạo một bản sao làm việc cục bộ) vì vậy không có lý do gì nó không thể thực hiện một số thao tác tương tự trên máy chủ và chỉ gửi đầu ra có liên quan. Cấp, điều đó hiện không được thực hiện nhưng đó là do thiếu một tính năng, không phải là không thể cơ bản. Cá nhân tôi nghĩ rằng đó là một tính năng khá quan trọng, nhưng này, đó là một lý do tôi tránh git khi có thể.
Cơ bản

10

Có lẽ lệnh này có thể hữu ích:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

"Et voilà"


2
Điều này tải xuống một thư mục cụ thể của tệp cho mục đích lưu trữ, điều này không kéo một bản sao bạn có thể sửa đổi và đẩy lùi.
leetNightshade

Rất tuyệt. Có lẽ không thể chấp nhận như là giải pháp cho OP nhưng thực ra đó là những gì tôi đã làm vì tôi chỉ cần tìm kiếm nội dung của một thư mục lớn trong một repo thậm chí còn lớn hơn tôi chắc chắn không muốn tìm nạp và tôi không cần phải sửa đổi / đẩy.
Oliver

7

Nếu bạn muốn nhận được những thay đổi mới nhất trong một thư mục mà không cần nhập nó, bạn có thể làm:

$ git -C <Path to directory> pull

4

git clone --filter từ Git 2.19

Tùy chọn này thực sự sẽ bỏ qua việc tìm nạp các đối tượng không cần thiết từ máy chủ.

Tôi đã viết một câu trả lời chi tiết giải thích trạng thái hỗ trợ hiện tại tại: Làm cách nào để sao chép thư mục con của kho lưu trữ Git?

Rất có khả năng là bất cứ điều gì được thực hiện git clonetrong khu vực đó cũng sẽ có git pulltương tự.


1

Đã thử và thử nghiệm công trình này!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

Hy vọng điều này là hữu ích!


0

Đôi khi, bạn chỉ muốn xem xét các bản sao trước đó của tập tin mà không gặp phải sự khó khăn khi đi qua các khác biệt.

Trong trường hợp như vậy, thật dễ dàng để tạo một bản sao của kho lưu trữ và kiểm tra cam kết cụ thể mà bạn quan tâm và xem xét thư mục con trong kho lưu trữ nhân bản đó. Bởi vì tất cả mọi thứ là cục bộ, bạn chỉ có thể xóa bản sao này khi bạn hoàn thành.


-1

Đối với tất cả những gì phải vật lộn với các đường dẫn tệp lý thuyết và ví dụ như tôi đã làm, đây là một ví dụ trong thế giới thực: Microsoft cung cấp tài liệu và ví dụ của họ trên git hub, thật không may là họ tập hợp tất cả các tệp ví dụ của họ cho một số lượng lớn chủ đề trong kho lưu trữ này:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

Tôi chỉ quan tâm đến các tệp js Microsoft Dynamics trong đường dẫn

msdn-code-gallery-community-s-z/Sdk.Soap.js/

vì vậy tôi đã làm như sau

tạo một

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

tập tin trong thư mục kho lưu trữ của tôi trên đĩa

git sparse-checkout init

trong thư mục đó bằng cách sử dụng cmd trên windows

Nội dung tập tin của

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

Sdk.Soap.js/*

cuối cùng làm một

git pull origin master
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.