Một chút khó hiểu là đây:
Git không bao giờ xem những cái đó là các tập tin cá nhân. Git nghĩ mọi thứ là nội dung đầy đủ.
Git thường sử dụng băm 160 bit thay cho các đối tượng trong repo của chính nó. Một cây các tệp về cơ bản là một danh sách các tên và giá trị băm liên quan đến nội dung của mỗi (cộng với một số siêu dữ liệu).
Nhưng hàm băm 160 bit xác định duy nhất nội dung (trong vũ trụ của cơ sở dữ liệu git). Vì vậy, một cây có băm như nội dung bao gồm nội dung ở trạng thái của nó.
Nếu bạn thay đổi trạng thái nội dung của tệp, hàm băm của nó sẽ thay đổi. Nhưng nếu hàm băm của nó thay đổi, hàm băm liên quan đến nội dung của tên tệp cũng thay đổi. Đến lượt nó thay đổi hàm băm của "cây thư mục".
Khi cơ sở dữ liệu git lưu trữ một cây thư mục, cây thư mục đó ngụ ý và bao gồm tất cả nội dung của tất cả các thư mục con và tất cả các tệp trong đó .
Nó được tổ chức theo cấu trúc cây với các con trỏ (bất biến, có thể tái sử dụng) cho các đốm màu hoặc các cây khác, nhưng về mặt logic, nó là một ảnh chụp nhanh toàn bộ nội dung của toàn bộ cây. Các đại diện trong cơ sở dữ liệu git không phải là nội dung dữ liệu phẳng, nhưng về mặt logic thì đó là tất cả dữ liệu của nó và không có gì khác.
Nếu bạn tuần tự hóa cây thành một hệ thống tập tin, đã xóa tất cả các thư mục .git và bảo git thêm cây vào cơ sở dữ liệu của nó, bạn sẽ không thêm gì vào cơ sở dữ liệu - phần tử sẽ có sẵn.
Nó có thể giúp nghĩ về băm của git như một con trỏ đếm tham chiếu đến dữ liệu bất biến.
Nếu bạn xây dựng một ứng dụng xung quanh đó, một tài liệu là một loạt các trang, có các lớp, có các nhóm, có các đối tượng.
Khi bạn muốn thay đổi một đối tượng, bạn phải tạo một nhóm hoàn toàn mới cho nó. Nếu bạn muốn thay đổi một nhóm, bạn phải tạo một lớp mới, cần một trang mới, cần một tài liệu mới.
Mỗi khi bạn thay đổi một đối tượng, nó sẽ sinh ra một tài liệu mới. Tài liệu cũ tiếp tục tồn tại. Tài liệu mới và cũ chia sẻ hầu hết nội dung của chúng - chúng có cùng trang (trừ 1). Một trang có các lớp giống nhau (trừ 1). Lớp đó có cùng các nhóm (trừ 1). Nhóm đó có cùng các đối tượng (trừ 1).
Và tương tự, tôi có nghĩa là một bản sao, nhưng thực hiện nó chỉ là một con trỏ đếm tham chiếu đến cùng một đối tượng bất biến.
Một repo git là rất nhiều như thế.
Điều này có nghĩa là một thay đổi git đã cho chứa thông điệp cam kết của nó (dưới dạng mã băm), nó chứa cây công việc của nó và nó chứa các thay đổi cha của nó.
Những thay đổi cha mẹ chứa những thay đổi cha mẹ của họ, tất cả các cách trở lại.
Một phần của repo git chứa lịch sử là chuỗi thay đổi. Chuỗi thay đổi đó ở cấp độ trên cây "thư mục" - từ cây "thư mục", bạn không thể duy nhất nhận được một bộ thay đổi và chuỗi thay đổi.
Để tìm hiểu điều gì xảy ra với một tệp, bạn bắt đầu với tệp đó trong tập thay đổi. Những thay đổi đó có một lịch sử. Thông thường trong lịch sử đó, cùng một tệp có tên tồn tại, đôi khi có cùng nội dung. Nếu nội dung giống nhau, không có thay đổi nào đối với tệp. Nếu nó khác, có một sự thay đổi, và công việc cần phải được thực hiện để tìm ra chính xác những gì.
Đôi khi các tập tin bị mất; nhưng, cây "thư mục" có thể có một tệp khác có cùng nội dung (cùng mã băm), vì vậy chúng tôi có thể theo dõi theo cách đó (lưu ý; đây là lý do tại sao bạn muốn một tệp cam kết di chuyển một tệp tách khỏi cam kết -biên tập). Hoặc cùng tên tệp và sau khi kiểm tra tệp là đủ tương tự.
Vì vậy, git có thể chắp vá một "lịch sử tập tin".
Nhưng lịch sử tệp này xuất phát từ việc phân tích hiệu quả "toàn bộ thay đổi", không phải từ một liên kết từ một phiên bản của tệp này sang phiên bản khác.