Làm thế nào để git lưu trữ các tập tin?


225

Tôi mới bắt đầu học git và để làm như vậy, tôi bắt đầu đọc Sách cộng đồng Git , và trong cuốn sách này họ nói rằng SVN và CVS lưu trữ sự khác biệt giữa các tệp và git lưu trữ một ảnh chụp nhanh của tất cả các tệp.

Nhưng tôi không thực sự hiểu ý họ khi chụp. Có phải git thực sự tạo một bản sao của tất cả các tệp trong mỗi cam kết bởi vì đó là những gì tôi hiểu từ lời giải thích của họ.

PS: Nếu bất kỳ ai có nguồn tốt hơn để học git, tôi sẽ đánh giá cao nó.


20
Đây là một bài viết tuyệt vời giải thích chi tiết về cách hoạt động của git. Những gì bạn đang tìm kiếm có lẽ là § về cơ sở dữ liệu đối tượng.
greg0ire

Bài viết tuyệt vời có chứa các liên kết đến các tài nguyên tuyệt vời khác. Tôi đã có niềm vui với những điều này trong một vài giờ.
mihai

2
Tôi tìm thấy bài viết thực sự hay này mô tả git từ trong ra ngoài: maryrosecook.com/blog/post/git-from-the-inside-out
Sumudu

Câu trả lời:


275

Git bao gồm cho mỗi cam kết một bản sao đầy đủ của tất cả các tệp, ngoại trừ, đối với nội dung đã có trong repo Git, ảnh chụp nhanh sẽ chỉ vào nội dung đã nói thay vì sao chép nó.
Điều đó cũng có nghĩa là một số tệp có cùng nội dung chỉ được lưu trữ một lần.

Vì vậy, một snapshot về cơ bản là một cam kết, đề cập đến nội dung của cấu trúc thư mục.

Một số tài liệu tham khảo tốt là:

Bạn nói với Git rằng bạn muốn lưu ảnh chụp nhanh dự án của bạn bằng lệnh git commit và về cơ bản nó ghi lại một bảng kê khai tất cả các tệp trong dự án của bạn trông như thế nào tại thời điểm đó

Lab 12 minh họa cách lấy ảnh chụp nhanh trước đó


Các cuốn sách progit có mô tả toàn diện hơn về một bản chụp:

Sự khác biệt chính giữa Git và bất kỳ VCS nào khác (Bao gồm cả Subversion và bạn bè) là cách Git nghĩ về dữ liệu của nó.
Về mặt khái niệm, hầu hết các hệ thống khác lưu trữ thông tin dưới dạng danh sách các thay đổi dựa trên tệp. Các hệ thống này (CVS, Subversion, Perforce, Bazaar, v.v.) nghĩ về thông tin họ lưu giữ dưới dạng tập hợp các tệp và các thay đổi được thực hiện cho từng tệp theo thời gian

VCS dựa trên đồng bằng

Git không nghĩ hoặc lưu trữ dữ liệu theo cách này. Thay vào đó, Git nghĩ rằng dữ liệu của nó giống như một tập hợp các ảnh chụp nhanh của một hệ thống tệp nhỏ.
Mỗi khi bạn cam kết hoặc lưu trạng thái dự án của bạn trong Git, về cơ bản, nó sẽ chụp ảnh tất cả các tệp của bạn trông như thế nào vào thời điểm đó và lưu trữ một tham chiếu đến ảnh chụp nhanh đó.
Để hiệu quả, nếu các tệp không thay đổi, Git sẽ không lưu trữ tệp một lần nữa, chỉ là một liên kết đến tệp giống hệt trước đó mà nó đã được lưu trữ.
Git nghĩ về dữ liệu của nó giống như dưới đây:

VCS dựa trên ảnh chụp

Đây là một sự khác biệt quan trọng giữa Git và gần như tất cả các VCS khác. Nó khiến Git xem xét lại gần như mọi khía cạnh của kiểm soát phiên bản mà hầu hết các hệ thống khác được sao chép từ thế hệ trước. Điều này làm cho Git giống như một hệ thống tệp nhỏ với một số công cụ cực kỳ mạnh mẽ được xây dựng trên nó, thay vì chỉ đơn giản là một VCS.


Jan Hudec thêm nhận xét quan trọng này :

Mặc dù điều đó đúng và quan trọng ở cấp độ khái niệm, nhưng điều đó KHÔNG đúng ở cấp độ lưu trữ.
Git không sử dụng deltas để lưu trữ .
Không chỉ vậy, nhưng nó hiệu quả hơn trong bất kỳ hệ thống nào khác. Bởi vì nó không giữ lịch sử trên mỗi tệp, khi nó muốn thực hiện nén delta, phải mất mỗi blob, chọn một số đốm có khả năng giống nhau (sử dụng phương pháp phỏng đoán bao gồm xấp xỉ gần nhất của phiên bản trước và một số khác), cố gắng tạo ra deltas và chọn cái nhỏ nhất. Bằng cách này, nó có thể (thường, phụ thuộc vào các heuristic) tận dụng các tệp tương tự khác hoặc các phiên bản cũ tương tự như trước đây. Tham số "gói cửa sổ" cho phép hiệu suất giao dịch cho chất lượng nén delta. Mặc định (10) thường cho kết quả khá, nhưng khi không gian bị giới hạn hoặc để tăng tốc độ truyền mạng, git gc --aggressivesử dụng giá trị 250, làm cho nó chạy rất chậm, nhưng cung cấp thêm nén cho dữ liệu lịch sử.


4
@JanHudec điểm tốt. Tôi đã bao gồm nhận xét của bạn trong câu trả lời để dễ nhìn hơn.
VonC

1
Có ai biết thuật ngữ khoa học máy tính cho mẫu lưu trữ giống Git, hay còn gọi là lưu trữ giá trị dựa trên hàm băm không? (hoặc một cái gì đó tương tự)
Joannes Vermorel

34
Trong bối cảnh câu hỏi thực tế của OP, đoạn đầu tiên dường như thực sự sai lệch. Nó không phải cho đến khi bạn nhận được để đoạn cuối cùng mà chúng ta biết rằng, oh vâng, thực tế Git làm "cửa hàng [...] sự khác biệt giữa các tập tin. Thật mong rằng thông tin đã được gắn cờ lên hàng đầu chứ không phải chôn quá sâu. Điều đó nói rằng, nhờ vào ít nhất bao gồm câu chuyện có thật ở đâu đó trong câu trả lời của bạn;)
Josh O'Brien

1
@NickVolynkin Tuyệt vời! Tôi vui vì những câu trả lời đang tìm kiếm một lượng khán giả lớn hơn.
VonC

1
Một cuốn sách hay khác: Git From The bottom Up: ftp.newartisans.com/pub/git.from.bottom.up.pdf
Jonas Berlin

46

Git lưu trữ hợp lý từng tệp trong SHA1 của nó. Điều này có nghĩa là nếu bạn có hai tệp có cùng một nội dung trong kho lưu trữ (hoặc nếu bạn đổi tên tệp), chỉ có một bản sao được lưu trữ.

Nhưng điều này cũng có nghĩa là khi bạn sửa đổi một phần nhỏ của tệp và cam kết, một bản sao khác của tệp sẽ được lưu trữ. Cách git giải quyết điều này là sử dụng các tập tin gói. Thỉnh thoảng, tất cả các tệp tin lỏng lẻo (thực tế, không chỉ các tệp, mà cả các đối tượng chứa thông tin thư mục và cam kết) từ một repo được tập hợp và nén thành một tệp gói. Các tập tin gói được nén bằng zlib. Và các tập tin tương tự cũng được nén delta.

Định dạng tương tự cũng được sử dụng khi kéo hoặc đẩy (ít nhất là với một số giao thức), vì vậy những tệp đó không phải được nén lại.

Kết quả của việc này là một kho lưu trữ git, chứa toàn bộ bản sao làm việc không nén, các tệp gần đây không nén và các tệp cũ đã nén thường tương đối nhỏ, nhỏ hơn hai lần so với kích thước của bản sao làm việc. Và điều này có nghĩa là nó nhỏ hơn SVN repo với cùng một tệp, mặc dù SVN không lưu trữ lịch sử cục bộ.


1
ah vì vậy, đồng bóng là không gian hiệu quả hơn
Ben
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.