2012-01-15 27 views
10

Vì lợi ích của một thí nghiệm, cho phép nói bạn git log xác định như sau cam kếtSHA-1 của các cam kết được tính toán chỉ dựa trên nội dung của cây?

commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 // added 2nd file 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

Sau khi cam kết, .git/refs/heads/master điểm để 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438.

Hãy nói rằng, sau này, tôi tự chỉnh sửa file .git/refs/heads/master để trỏ đến 9188f9a25b045f130b08888bc3f638099fa7f212

Tại thời điểm này, tình trạng git nhận ra rằng một tập tin không bị giam mới là cần được chăm sóc. Đây là cùng một tệp mà lần commit thứ hai của tôi xử lý trước đây.

Nếu tôi cam kết nó .. git log hiện nay cho thấy

commit b317f67686f9e6ab1eaabf47073b401d677205d5 // 2nd file committed for the 2nd time 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

Câu hỏi 1:

Bạn sẽ nhận thấy rằng SHA băm khác nhau giữa lần đầu tiên tôi cam kết một tập tin thứ hai và hiện nay. Tại sao vậy? Nội dung của tệp không thay đổi, nó vẫn là tệp chính xác.

Câu hỏi 2

Tại thời điểm này, những gì đã xảy ra với bản gốc thứ hai cam kết? Khi tôi làm git show 16bc8486, nó cho thấy cam kết này. Tuy nhiên, nó không hiển thị trong lịch sử git log.

+1

Đọc thú vị: http://book.git-scm.com/1_the_git_object_model.html – Mat

Trả lời

14

Câu hỏi 1: Bởi vì băm được tạo ra để đưa mọi thứ vào tài khoản bao gồm dữ liệu meta cam kết (chính nó chứa ngày và giờ).

Câu hỏi 2: git log hiển thị nhật ký của nhánh hiện tại. Cam kết 16bc8486 không phải là một phần của nó. Theo như tôi biết (tôi không hoàn toàn chắc chắn) người thu gom rác sẽ lấy nó sớm hay muộn, nếu nó thấy nó không có gì liên quan đến nó (git gc --help) ..

+0

Vào Q2, 'git branch' chỉ hiển thị một chi nhánh tồn tại tại thời điểm này - * master. Bây giờ nhánh nào là tệp cũ? – JAM

+0

@JAM: nó không phải là một phần của bất kỳ chi nhánh nào, đó là lý do tại sao nó là ứng cử viên cho việc thu gom rác thải. Bạn có thể "giải cứu" nó bằng cách tạo một nhánh rõ ràng trên commit đó 'git branch branch_name commit_hash'. – Mat

+0

@Mat, nếu một thời gian trôi qua và băm đó không có sẵn, có thể phục hồi bằng cách nào đó không? – JAM

2

SHA1 được tính từ điểm khác biệt và tất cả dữ liệu meta từ cam kết này (bao gồm tác giả và người gửi, dấu thời gian và các dữ liệu khác).

Đối với câu hỏi thứ hai của bạn, cam kết dữ liệu vẫn còn hiện diện nhưng không phải là một phần của bất kỳ chi nhánh trực tiếp nào nữa. Đôi khi git sẽ chạy một bộ sưu tập rác nơi nhiều nội dung bị xóa thực sự sẽ bị xóa. Bạn sẽ nhận thấy rằng một khi bạn tự chạy nó bằng cách sử dụng git gc rằng cam kết không được chấp nhận sẽ biến mất và thậm chí không thể truy cập được với git show nữa.

6

Giá trị sha1 cho mỗi tệp blobs sẽ giống hệt nhau trong cả hai trường hợp nếu bạn có cùng nội dung (ngay cả khi tên tệp được thay đổi).

Tương tự, giá trị sha1 cho các hình ảnh cây của các đốm màu tệp sẽ giống nhau nếu chúng có cùng tên tệp.

Tuy nhiên ở phía trên rất chúng ta có cam mà sẽ chứa các liên kết không thay đổi đến trước cam kết, cây hàng đầu, tác giả và commiter, nhưng như KingCrunch nói, tác giả và commiter ngày sẽ khác nhau , do đó, sha1 của cam kết sha1 sẽ khác nhau.

Bạn có thể làm cho chúng giống nhau nếu bạn cố tình đặt ngày tác giả và ngày kết thúc bằng cách sử dụng các biến môi trường để chúng không thay đổi.

+0

Hệ quả thêm; Nếu người ta làm cho chúng giống hệt nhau thì chúng sẽ giống hệt như kho lưu trữ đối tượng và đồ thị chi nhánh có liên quan. Nó sẽ giống như sự chia rẽ ban đầu, nhưng giống hệt nhau chưa bao giờ xảy ra - chúng không thể phân biệt được! Đi săn vui nhé. –

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