2014-10-21 18 views
6

Khi cố gắng hiểu JGit: Retrieve tag associated with a git commit, tôi đã đến chuỗi này trên danh sách gửi thư của JGit: [jgit-dev] Commits and tags.Vỏ có nghĩa là gì trong Git?

Trong chủ đề này, họ tham khảo các phương pháp peel của org.eclipse.jgit.lib.Repository:

Peel một tài liệu tham khảo có thể chưa gọt vỏ để một thẻ chú thích.

Tôi chỉ có thể tìm thấy hai đề cập về lột trong tài liệu Git: git-check-ref-format(1) Manual PageGit Internals - Maintenance and Data Recovery.

Thuật ngữ bóc vỏ có ý nghĩa gì trong Git? Nó hữu ích như thế nào? Nó phải làm gì với hành động ?

Trả lời

8

Bạn đã biết rằng mỗi đối tượng trong một kho lưu trữ có một SHA-1 duy nhất và cũng là một loại và nội dung liên quan. (Từ dòng lệnh, sử dụng git cat-file -t sha1 để xem loại đối tượng nhất định và git cat-file -p sha1 để xem nội dung, có thể với một số ứng dụng in ấn khá nhưng thường có định dạng thô.)

Đối tượng thẻ được chú thích trong git kho chứa một SHA-1. : Tôi hy vọng phần này rõ ràng và không gây tranh cãi. :-))

Thông thường, SHA-1 bên trong đối tượng thẻ được chú thích — hãy gọi đây là "target-ID" và đối tượng được đặt tên là "target" của thẻ — là ID của đối tượng cam kết. Trong trường hợp này, tất cả vẫn còn khá rõ ràng và đơn giản. Nhưng nếu nó không?

Cụ thể, mục tiêu của thẻ được chú thích có thể là một thẻ được chú thích khác. Nếu trường hợp này xảy ra, bạn phải tìm nạp thẻ chú thích thứ hai có chứa một ID mục tiêu khác. Bạn phải lặp lại quá trình này, bóc thẻ sau thẻ, cho đến khi bạn đến một đối tượng không gắn thẻ. Lý tưởng nhất đây sẽ là một cam kết, nhưng tất nhiên nó có thể là bất kỳ của ba loại đối tượng còn lại (nó không rõ ràng nó có nghĩa là để gắn thẻ một cây hoặc blob mặc dù; chỉ có một cam kết có ý nghĩa).

Quá trình "bóc vỏ" này đã được so sánh với việc lột hành tây và đó là nơi cụm từ bắt nguồn. Lưu ý rằng nếu bạn đang viết bộ kiểm tra sức khỏe kho lưu trữ, có thể là khôn ngoan để đảm bảo rằng chuỗi thẻ không lặp lại (ví dụ: nếu thẻ 12345677654321 làm mục tiêu và 7654321 là thẻ được chú thích với 1234567 là mục tiêu của nó?). (Edit: như remram chỉ ra trong một bình luận, điều này đòi hỏi "phá vỡ" SHA-1. Điều đó có nghĩa là nó hầu như không thể xảy ra trong thực tế, cũng giống như bạn sẽ không nhận được một cây đệ quy chỉ đến chính nó.)

Edit: làm thế nào để làm cho một thẻ trỏ đến một thẻ khác:

... make a repo with a commit that can be tagged ... 
$ git tag -a anno1 -m 'annotated tag' 
$ git tag -a anno2 anno1 -m 'another tag' 
$ git cat-file -p anno1 
object d4ec8b2d465de0c087d645f52ba5040586b8ce0f 
type commit 
tag anno1 
tagger Chris Torek <[email protected]> 1413933523 -0600 

annotated tag 
$ git cat-file -p anno2 
object cd1e0637c348e46c645819ef6de36679052b4b7f 
type tag 
tag anno2 
tagger Chris Torek <[email protected]> 1413934239 -0600 

another tag 
+0

Điều này là sai. Đối tượng thẻ được chú thích chỉ có thể trỏ đến cam kết đối tượng, chứ không phải các thẻ khác.Và chuỗi các thẻ không thể lặp lại vì cùng một lý do mà các chuỗi cam kết không lặp lại - hàm SHA1 không thể đảo ngược. – remram

+1

@remram: điểm về SHA-1 là không thể đảo ngược là hợp lệ, ngoại trừ việc có tuyên bố đã phá vỡ nó (tôi không chắc liệu có nên tin họ) hay ít nhất là có khả năng phá vỡ nó. Đối với các thẻ không trỏ đến thẻ, đúng là 'git tag -a' không thực hiện theo mặc định, nhưng tôi có thể tạo thẻ trỏ đến thẻ khác; Tôi sẽ chỉnh sửa bài đăng. Nó hoạt động khá tốt: 'git show anno3' hiển thị thẻ trỏ đến thẻ' anno1' và sau đó commit bên dưới trên 'anno1' (' anno2' là một bản demo 'git tag -a' dùng cho commit bên dưới). – torek

+1

(Cập nhật: nó dễ dàng hơn tôi mong đợi, tôi đã làm nó như là 'anno1' với' anno2' trỏ đến 'anno1'.) – torek

2

"lột" đề cập đến cuộc hội thảo, ví dụ: đi từ một ref đến đối tượng thẻ chú thích đến một ref trên cam kết nó trỏ đến.

Cụm từ này cũng được sử dụng cho các trường hợp khác của cú pháp ^{xxx}, ví dụ: đi từ cam kết đến cây với abc1234^{tree}.

+0

tôi đã tự hỏi những gì mà '^ {}' cú pháp là gì. Tốt nhất, cảm ơn. –