2010-02-25 43 views
64

Với sparse checkout feature mới trong Git 1.7.0, bạn có thể lấy nội dung của thư mục con giống như cách bạn có thể làm trong SVN? Tôi tìm thấy this example, nhưng nó giữ nguyên cấu trúc thư mục đầy đủ. Hãy tưởng tượng rằng tôi chỉ muốn nội dung của thư mục 'perl', mà không có một thư mục thực sự có tên 'perl'.Thanh toán thưa thớt trong Git 1.7.0?

- EDIT -

Ví dụ:

kho git của tôi chứa các đường dẫn sau

repo/.git/ 
repo/perl/ 
repo/perl/script1.pl 
repo/perl/script2.pl 
repo/images/ 
repo/images/image1.jpg 
repo/images/image2.jpg 
repo/doc/ 
repo/doc/readme.txt 
repo/doc/help.txt 

Những gì tôi muốn là để có thể sản xuất ra từ kho lưu trữ trên bố trí này :

repo/.git/ 
repo/script1.pl 
repo/script2.pl 

Tuy nhiên wi Tính năng thanh toán thưa thớt hiện tại, có vẻ như chỉ có thể nhận được

repo/.git/ 
repo/perl/script1.pl 
repo/perl/script2.pl 

không phải là điều tôi muốn.

+4

cuối cùng họ đã triển khai! mát mẻ! –

+0

Tại sao? Vấn đề là gì? Và tại sao bạn muốn có cấu trúc thư mục khác nhau trong kho lưu trữ và khác nhau cục bộ? Không có ý nghĩa nhiều trong nháy mắt đầu tiên. –

+2

@Jiri: Tôi có một ứng dụng web với mã hành động (phía máy khách) và mã PHP (phía máy chủ). Các tập tin có liên quan chặt chẽ, vì vậy tôi muốn đặt chúng trong một repo/chi nhánh duy nhất. Tuy nhiên tôi không muốn các tập tin nguồn ActionScript trên máy chủ, chỉ có các tập tin PHP. – davr

Trả lời

23

Bạn vẫn cần sao chép toàn bộ kho lưu trữ, sẽ có tất cả các tệp. Bạn có thể sử dụng cờ --depth để chỉ truy xuất số lượng lịch sử hạn chế.

Khi kho lưu trữ được nhân bản, thủ thuật đọc cây chỉ giới hạn "chế độ xem" của bạn trong kho lưu trữ cho các tệp hoặc thư mục có trong tệp .git/info/sparse-checkout.

Tôi đã viết một kịch bản nhanh chóng để giúp quản lý thưa thớt, vì tại thời điểm này nó là một chút không thân thiện:

#!/bin/sh 
echo > .git/info/sparse-checkout 
for i in "[email protected]" 
do 
    echo "$i" >> .git/info/sparse-checkout 
done 
git read-tree -m -u HEAD 

Nếu bạn lưu kịch bản này như git-sparse.sh vào con đường báo cáo bằng cách gọi git --exec-path, sau đó bạn có thể chạy git sparse foo/ bar/ để chỉ "thanh toán" các thư mục foo và bar hoặc git sparse '*' để nhận lại mọi thứ.

+0

Cảm ơn sự giúp đỡ, nhưng điều đó dường như không trả lời câu hỏi của tôi. Xem câu hỏi được cập nhật của tôi để làm rõ. – davr

+3

Vâng, thưa thớt chỉ là một cách để lọc cây thực tế, nó không thể di chuyển các tập tin xung quanh. Vì vậy, bạn không thể làm những gì bạn muốn ... – richq

16

Câu trả lời ngắn gọn là không. Git xem tất cả các tệp dưới dạng một đơn vị.

Điều tôi khuyên bạn nên chia nhỏ kho lưu trữ thành các khối logic. Một phần riêng biệt cho perl, hình ảnh và tài liệu. Nếu bạn cũng cần phải duy trì phong cách repo uber bạn có thể tạo một repo tạo thành Submodules.

5

Bây giờ, không cắt giảm chi tiết về lý do bạn muốn làm điều này, có thể dễ dàng giải quyết vấn đề của bạn bằng liên kết/lối tắt.

Để trả lời câu hỏi - không, và với lý do có ý nghĩa. Toàn bộ lịch sử của repo được tải xuống ngay cả với một 'thanh toán thưa thớt'. Để làm rõ lý do tại sao điều này là cần thiết - nếu không theo dõi các tệp được đổi tên sẽ là một cơn đau ở cổ .... Hãy tưởng tượng bạn di chuyển tệp /repo_root/asd/file1.cpp sang /repo_root/fgh/file1.cpp - bây giờ nếu bạn chỉ tải xuống /repo_root/fgh vùng đồng bằng, bạn sẽ không biết về tệp1.cpp. Vì vậy, điều này có nghĩa là bạn phải tải xuống tất cả các vùng đồng bằng. Nhưng sau đó bạn có một kho lưu trữ đầy đủ; không chỉ là một thư mục cắt của nó, do đó chỉ cần /rero_root/fgh thư mục không phải là một repo chính nó. Điều này có thể không âm thanh quan trọng khi bạn kiểm tra, nhưng khi bạn cam kết, git có thể không biết đủ để làm việc alright.

Cách giải quyết: Nếu bạn thực sự muốn, bạn có thể tạo một kịch bản mà các cuộc gọi git-thanh toán theo cách như vậy (đối với vỏ sh, hàng loạt cho các cửa sổ không nên cứng để sản xuất):

!/bin/sh 
curDir=`pwd` 
cd $2 
git-checkout $1 
cp -R $3/* $4 
cd $curDir 

Ở đây đối số đầu tiên là nhánh thanh toán, thư mục thứ hai - thư mục repo hiện tại, thư mục thứ ba - thư mục con bạn muốn sử dụng và thứ tư - vị trí bạn muốn sao chép.

Cảnh báo: kỹ năng vỏ của tôi hầu như không tồn tại, vì vậy hãy sử dụng kỹ năng này sau khi thử nghiệm. Nó không phải là khó khăn để tạo lại sự đảo ngược của kịch bản này, mà sao chép trở lại công cụ, để nó có thể được cam kết repo.

+0

Có toàn bộ lịch sử của repo không phải là một vấn đề, nó không phải là một repo lớn, và chúng tôi có rất nhiều không gian đĩa. Tôi đoán trường hợp sử dụng cụ thể của chúng tôi không phải là phổ biến, vì vậy các nhà phát triển git không bao giờ nghĩ để thêm nó. Đó là một trong rất ít điều mà SVN làm việc tốt hơn cho chúng tôi (git có 99 thứ khác tốt hơn, đó là lý do tại sao chúng tôi chuyển đổi, nhưng vẫn còn) – davr

+0

liên kết tượng trưng trên cửa sổ là một cơn ác mộng - điều này không thể thực hiện được. –

+0

lulz tại cửa sổ guy – nottinhill

3

git filter-branch --subdirectory-filter là những gì bạn cần, xem Detach (move) subdirectory into separate Git repository.

Đây là một tập lệnh bash nhỏ để thực hiện điều đó.

Điều này trước tiên sẽ tạo bản sao làm việc của repo gốc, sau đó lọc chi nhánh bằng bộ lọc thư mục con để bạn có được những gì bạn muốn.

#!/bin/bash 
# 
# git-subdir.sh 
# 
git clone --no-hardlinks $1 $2 

cd $2 

git filter-branch --subdirectory-filter $2 --prune-empty --tag-name-filter cat HEAD -- --all 

git reset --hard 

git remote rm origin 

refbak=$(git for-each-ref --format="%(refname)" refs/original/) 

if [ -n "$refbak" ];then 
    echo -n $refbak | xargs -n 1 git update-ref -d 
fi 

git reflog expire --expire=now --all 

git repack -ad 

git gc --aggressive --prune=now 

Sử dụng ví dụ trong câu hỏi, git-subdir.sh repo perl sẽ hoạt động.

0

Dường như những gì bạn đang cố gắng làm là đổi tên cây thư mục sao cho tệp của bạn kết thúc ở một vị trí khác. Nó xuất hiện với tôi rằng những gì bạn đang yêu cầu làm là chống mẫu để quản lý mã/dự án trên hai lần đếm: phân loại mô-đun (bit java dưới nút java, perl dưới nút perl) và có dự án với các tệp ở các vị trí khác nhau từ nơi nhà phát triển trực quan hóa chúng. Kể từ khi git duy trì băm nội dung thư mục để xem những gì được thay đổi, điều này cũng phá vỡ git như vậy.

Daemeon Reiydelle

Các vấn đề liên quan