Hãy để tôi khám phá lý do tại sao đây là một vấn đề đầy thách thức khi sử dụng nội bộ git. Bạn có thể nhận được sha1 của cam kết hiện tại bằng cách
#!/bin/bash
commit=$(git cat-file commit HEAD) #
sha1=($((printf "commit %s\0" $(echo "$commit" | wc -c); echo "$commit") | sha1sum))
echo ${sha1[0]}
Về cơ bản, bạn chạy tổng kiểm tra sha1 trên tin nhắn được trả về git cat-file commit HEAD
. Hai điều ngay lập tức nhảy ra như một vấn đề khi bạn kiểm tra tin nhắn này. Một là cây sha1 và thứ hai là thời gian cam kết.
Bây giờ thời gian cam kết dễ dàng được quan tâm bằng cách thay đổi tin nhắn và đoán mất bao lâu để thực hiện một cam kết hoặc lên lịch để cam kết tại một thời điểm cụ thể. Vấn đề thực sự là cây sha1, mà bạn có thể nhận được từ git ls-tree $(git write-tree) | git mktree
. Về cơ bản, bạn đang thực hiện tổng kiểm tra sha1 trên tin nhắn từ ls-tree, đây là danh sách tất cả các tệp và tổng kiểm tra sha1 của chúng.
Do đó, tổng kiểm tra sha1 của bạn phụ thuộc vào tổng kiểm tra cây sha1 của bạn, điều này phụ thuộc trực tiếp vào các tập tin kiểm tra sha1, hoàn thành vòng tròn và phụ thuộc vào cam kết sha1. Vì vậy, bạn có một vấn đề tròn với các kỹ thuật có sẵn cho bản thân mình.
Với tổng kiểm tra kém an toàn hơn , người ta đã chứng minh có thể ghi tổng kiểm tra của tệp vào chính tệp thông qua lực lượng vũ phu; tuy nhiên, tôi không biết bất kỳ công việc nào đã hoàn thành nhiệm vụ đó với sha1. Điều này không phải là không thể, nhưng bên cạnh không thể với sự hiểu biết hiện tại của chúng tôi (nhưng ai biết có thể trong một vài năm nữa, nó sẽ là tầm thường). Tuy nhiên, điều này thậm chí còn khó hơn đối với vũ lực vì bạn phải viết tổng kiểm tra (cam kết) của tổng kiểm tra (cây) của tổng kiểm tra (blob) vào tệp.