2010-02-12 33 views
16

Dưới đây là các vấn đề:Có thể giữ một tập tin không phiên bản trong một kho git

Tôi tạo ra kho git trần tại nơi đối tác lưu trữ của tôi, mà tôi sử dụng như kho lưu trữ tài liệu tham khảo từ tất cả các địa điểm/máy tính tôi duy trì dự án của tôi từ.

Vấn đề là dự án của tôi đang sử dụng tệp db sqlite, thường xuyên phát triển (hiện tại khoảng 150MB). Khi thời gian trôi qua, thư mục .git của tôi ngày càng lớn hơn (gần đây khoảng 1GB). Và không gian lưu trữ của tôi bị giới hạn.

Tôi cần kho trống để chứa phiên bản HEAD của tệp db này nhưng tôi thực sự không cần giữ lịch sử phiên bản của nó.

Vì vậy, để đạt được một số không gian, theo thời gian, tôi xóa tệp db khỏi lịch sử, xóa kho lưu trữ và tạo lại phiên bản trống. Điều này làm việc, nhưng là một nỗi đau.

Có cách nào để yêu cầu git chỉ giữ phiên bản cuối cùng của tệp và xóa lịch sử của tệp không?

+1

câu hỏi có liên quan: http://stackoverflow.com/questions/540535/managing-large-binary-files-with-git – jfs

+0

điều này có thể không phải là giải pháp trực tiếp nhưng tại sao không giữ tệp cơ sở dữ liệu không được theo dõi và tạo tập lệnh đồng bộ hóa tệp của bạn với tệp trong kho lưu trữ chính? –

+0

Tại sao bạn cần tệp db này, để giữ một bản sao của lược đồ, hoặc dữ liệu? Hoặc cả hai? –

Trả lời

5

Câu trả lời ngắn gọn: không.

Câu trả lời hữu ích hơn: Git không theo dõi tệp một cách riêng lẻ, vì vậy yêu cầu bỏ đi lịch sử của một tệp sẽ có nghĩa là phải ghi lại toàn bộ lịch sử của nó hoàn toàn theo mọi cam kết và dẫn đến tất cả các loại vấn đề xấu xí.

Bạn có thể lưu trữ tệp trong thẻ được chú thích, nhưng điều đó không thuận tiện lắm. Về cơ bản nó đi như thế này:

ID=`git hash-object -w yourfile.sqlite` 
git tag -a -m "Tag database file" mytag $ID 

Trong không có cách nào đó thuận tiện cập nhật (hoặc thậm chí tạo) các tập tin cơ sở dữ liệu trong cây làm việc cho bạn ... bạn sẽ phải sử dụng các kịch bản móc để thi đua đó.

Tiết lộ đầy đủ: Tôi không hoàn toàn chắc chắn liệu thực sự có thể đẩy các đốm màu được gắn thẻ không được bao gồm trong lịch sử bình thường hay không. Tôi nghi ngờ rằng nó không phải là, trong trường hợp này công thức này sẽ ít hơn rất nhiều hữu ích.

3

Bạn luôn có thể sử dụng .gitignore tệp cấu hình cho việc này - ngay từ đầu.

Và ... (từ this thread: thanh danh cho Björn Steinbrink)

Sử dụng filter-branch để thả cha mẹ vào ngày đầu tiên cam kết bạn muốn giữ lại, và sau đó thả các cruft cũ.

Giả sử $drop là mã băm của cam kết mới nhất mà bạn muốn xóa. Để giữ cho mọi thứ lành mạnh và đơn giản, hãy đảm bảo cam kết đầu tiên bạn muốn giữ lại, tức là. con của $drop, không phải là kết hợp cam kết. Sau đó, bạn có thể sử dụng:

git filter-branch --parent-filter "sed -e 's/-p $drop//'" \ 
    --tag-name-filter cat -- \ 
    --all ^$drop 

Trên đây viết lại cha mẹ của tất cả cam kết mà đến "sau" $drop.

Kiểm tra kết quả bằng gitk.

Sau đó, để làm sạch tất cả các tàu tuần dương cũ.

Thứ nhất, tài liệu tham khảo sao lưu từ filter-branch:

git for-each-ref --format='%(refname)'refs/original | \ 
    while read ref 
    do 
      git update-ref -d "$ref" 
    done 

Sau đó làm sạch reflogs của bạn:

git reflog expire --expire=0 --all 

Và cuối cùng, đóng gói lại và thả tất cả các đối tượng không thể kết nối cũ: git đóng gói lại -ad git prune # Đối với các đối tượng mà repack -ad có thể đã để lại xung quanh

Tại thời điểm đó, mọi điều dẫn lên đến và bao gồm thả $ nên được biến mất.

+0

Tôi đang tìm một giải pháp * giữ * bản sao của db trong kho lưu trữ –

+0

Sau đó, bạn có thể tạo tập lệnh xóa lịch sử sau mỗi lần commit. –

4

Có vẻ như bạn đang tìm kiếm giải pháp cho vấn đề không đúng.

Tệp nhị phân lớn thường cần được lưu trữ trong kho, nhưng tôi không nghĩ rằng cơ sở dữ liệu SQLite là thứ bạn thực sự cần lưu trữ ở dạng nhị phân trong kho lưu trữ.

Thay vào đó, bạn nên giữ lược đồ trong điều khiển phiên bản và nếu bạn cần giữ dữ liệu, hãy tuần tự hóa nó (thành XML, JSON, YAML ...) và phiên bản đó. Một kịch bản xây dựng có thể tạo cơ sở dữ liệu và unserialize dữ liệu vào nó khi cần thiết.

Vì định dạng tuần tự dựa trên văn bản có thể được theo dõi hiệu quả bởi Git, bạn sẽ không phải lo lắng về chi phí không gian của việc lưu giữ các phiên bản trước đây ngay cả khi bạn không nghĩ mình cần truy cập vào chúng.

+0

làm như vậy sẽ cho phép git áp dụng các kỹ thuật nén và phổ biến thông thường của nó làm cho điều này ít đau đớn hơn nhiều. Điều duy nhất để chăm sóc sẽ là tạo ra một định dạng tuần tự sắp xếp đúng cách sẽ giảm thiểu kích thước của diff. –

+0

Tôi không đồng ý. Nếu bạn nhìn vào định dạng slite, nó không phải là nhị phân. Git hoàn toàn có thể tạo ra một số khác biệt có thể sử dụng với nó. Lợi ích duy nhất sẽ là sự khác biệt sẽ dễ đọc hơn trong trường hợp xung đột. Có để xử lý một lớp serialization văn bản là quá nhiều công việc nếu bạn hỏi tôi –

+0

Đây là một ý tưởng tuyệt vời ... là có một kịch bản yêu thích bạn có để làm serialization dựa trên văn bản? – AlexMA

0

Nếu tôi hiểu câu hỏi của bạn, tôi nghĩ rằng tôi có một giải pháp đơn giản.

  1. Trước tiên hãy sao lưu tệp ở đâu đó,
  2. Xóa tệp khỏi thư mục/cây làm việc của bạn. Không git rm, chỉ rm thôi.
  3. Thực hiện cam kết.
  4. Đảm bảo tệp được thêm vào .gitignore.

Khi cam kết tiếp theo, GIT sẽ không còn cố gắng thêm tệp đó nữa. Lưu ý rằng bạn vẫn sẽ có tệp được lưu trữ trong các cam kết trước đó. Chỉ là bạn sẽ không thêm nó vào mọi cam kết bạn làm trong tương lai. Để xóa nó khỏi các cam kết trước đó, bạn sẽ cần lời khuyên từ một người có nhiều kinh nghiệm GIT hơn tôi.

0

Thêm sqlite.db vào tệp .gitignore của bạn.

Để check-in db hiện tại cho (tiềm năng) đẩy với các chi nhánh hiện tại:

branch="$(sed 's,.*refs/heads/,,' "$(git rev-parse --git-dir)"/HEAD)" 
objectname=$(git hash_object -w "$(git rev-parse --show-toplevel)/sqlite.db") 
git tag -f db_heads/$branch $objectname 

khi đẩy một chi nhánh:

git push origin $branch +db_heads/$branch 

Khi lấy một chi nhánh:

git fetch origin $branch tags/db_heads/$branch:tags/db_heads/$branch 

khi thanh toán chi nhánh:

git checkout $branch 
git cat-file -p db_heads/$branch >"$(git rev-parse --show_toplevel)/sqlite.db" 

Và điều đó nên làm điều đó, tôi nghĩ vậy.

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