Cam kết-ish và tree-ish trong Git là gì?


117

Câu hỏi

Các ví dụ cụ thể về commit-ish và tree-ish trong Git là gì?

Câu hỏi Stack Overflow "Tree-ish nghĩa là gì trong git?" giao dịch cụ thể với tree-ish, nhưng tôi muốn hiểu thêm về cả hai .

Lý lịch

Tập quán trong Tài liệu

Tài liệu Git đưa ra một số tham chiếu đến "commit-ish" và "tree-ish". Ví dụ: nếu bạn đang kiểm tra mã nguồn Git :

$ git grep --files-with-matches --extended-regexp "commit(-)*ish"
config.txt
git-describe.txt
git-fast-import.txt
git-name-rev.txt
git-push.txt
git-rebase.txt
git-rev-parse.txt
git.txt
gitcli.txt
glossary-content.txt
howto/revert-branch-rebase.txt
revisions.txt

$ git grep --files-with-matches --extended-regexp "tree(-)*ish" | \
$ grep --invert-match RelNotes
diff-format.txt
diff-generate-patch.txt
git-archive.txt
git-cat-file.txt
git-checkout.txt
git-diff-index.txt
git-diff-tree.txt
git-ls-files.txt
git-ls-tree.txt
git-merge-tree.txt
git-read-tree.txt
git-reset.txt
git-svn.txt
git.txt
gitcli.txt
gittutorial-2.txt
glossary-content.txt
revisions.txt

Định nghĩa

Tài liệu Git định nghĩa "commit-ish" và "tree-ish" là gì :

<tree>

Cho biết tên đối tượng cây.

<commit>

Cho biết tên đối tượng cam kết.

<tree-ish>

Cho biết một cây, cam kết hoặc tên đối tượng gắn thẻ Một lệnh có <tree-ish> đối số cuối cùng muốn hoạt động trên một <tree>đối tượng nhưng tự động bỏ qua các tham chiếu <commit><tag>các đối tượng trỏ đến<tree> .

<commit-ish>

Cho biết tên đối tượng cam kết hoặc thẻ. Một lệnh có <commit-ish> đối số cuối cùng muốn hoạt động trên một <commit>đối tượng nhưng tự động bỏ tham chiếu đến <tag>các đối tượng trỏ đến<commit> .

Tài liệu không đủ rõ ràng

Mặc dù tài liệu ở trên định nghĩa "commit-ish" và "tree-ish" là gì, tôi vẫn thấy nó quá mơ hồ và không rõ ràng.

Các ví dụ cụ thể về "commit-ish" và "tree-ish" là gì, và chúng khác nhau như thế nào?

Câu trả lời:


156

Câu trả lời ngắn (TL; DR)

Dưới đây là danh sách đầy đủ các định danh cam kết và định danh cây (từ tài liệu sửa đổi Git ):

----------------------------------------------------------------------
|    Commit-ish/Tree-ish    |                Examples
----------------------------------------------------------------------
|  1. <sha1>                | dae86e1950b1277e545cee180551750029cfe735
|  2. <describeOutput>      | v1.7.4.2-679-g3bee7fb
|  3. <refname>             | master, heads/master, refs/heads/master
|  4. <refname>@{<date>}    | master@{yesterday}, HEAD@{5 minutes ago}
|  5. <refname>@{<n>}       | master@{1}
|  6. @{<n>}                | @{1}
|  7. @{-<n>}               | @{-1}
|  8. <refname>@{upstream}  | master@{upstream}, @{u}
|  9. <rev>^                | HEAD^, v1.5.1^0
| 10. <rev>~<n>             | master~3
| 11. <rev>^{<type>}        | v0.99.8^{commit}
| 12. <rev>^{}              | v0.99.8^{}
| 13. <rev>^{/<text>}       | HEAD^{/fix nasty bug}
| 14. :/<text>              | :/fix nasty bug
----------------------------------------------------------------------
|       Tree-ish only       |                Examples
----------------------------------------------------------------------
| 15. <rev>:<path>          | HEAD:README.txt, master:sub-directory/
----------------------------------------------------------------------
|         Tree-ish?         |                Examples
----------------------------------------------------------------------
| 16. :<n>:<path>           | :0:README, :README
----------------------------------------------------------------------

Các mã định danh # 1-14 đều là "commit-ish", vì tất cả chúng đều dẫn đến các cam kết, nhưng vì các cam kết cũng trỏ đến cây thư mục, cuối cùng tất cả chúng đều dẫn đến các đối tượng cây thư mục (con) và do đó cũng có thể được sử dụng như "cây -nói ”.

# 15 cũng có thể được sử dụng dưới dạng tree-ish khi nó tham chiếu đến một thư mục (con), nhưng nó cũng có thể được sử dụng để xác định các tệp cụ thể. Khi nó đề cập đến các tệp, tôi không chắc liệu nó có còn được coi là "tree-ish" hay không hay nó hoạt động giống "blob-ish" hơn (Git đề cập đến các tệp là "blobs").

Câu trả lời dài

Cam kết và cây thư mục trong Git

Ở các cấp thấp nhất, Git theo dõi mã nguồn bằng bốn đối tượng cơ bản:

  1. Các thẻ được chú thích, trỏ đến các cam kết.
  2. Cam kết, trỏ đến cây thư mục gốc của dự án của bạn.
  3. Cây, là thư mục và thư mục con.
  4. Blobs, là các tập tin.

Mỗi đối tượng này đều có ID băm sha1 của riêng nó, vì Linus Torvalds đã thiết kế Git giống như một hệ thống tệp có địa chỉ nội dung , tức là các tệp có thể được truy xuất dựa trên nội dung của chúng (ID sha1 được tạo từ nội dung tệp). Sách Pro Git đưa ra sơ đồ ví dụ này :

Hình 9-3 từ sách Pro Git

Commit-ish vs Tree-ish

Nhiều lệnh Git có thể chấp nhận các số nhận dạng đặc biệt cho các cam kết và cây thư mục (con):

  • "Commit-ish" là các định danh cuối cùng dẫn đến một đối tượng cam kết. Ví dụ,

    tag -> commit

  • "Tree-ish" là các định danh cuối cùng dẫn đến các đối tượng cây (tức là thư mục).

    tag -> commit -> project-root-directory

Bởi vì các đối tượng cam kết luôn trỏ đến một đối tượng cây thư mục (thư mục gốc của dự án của bạn), bất kỳ số nhận dạng nào là "commit-ish", theo định nghĩa, cũng là "tree-ish". Nói cách khác, bất kỳ mã định danh nào dẫn đến đối tượng cam kết cũng có thể được sử dụng để dẫn đến đối tượng cây thư mục (con) .

Nhưng vì các đối tượng cây thư mục không bao giờ trỏ đến các cam kết trong hệ thống lập phiên bản của Git, nên không phải mọi mã định danh trỏ đến cây thư mục (con) cũng có thể được sử dụng để trỏ đến một cam kết. Nói cách khác, tập hợp các số nhận dạng "commit-ish" là một tập hợp con nghiêm ngặt của bộ số nhận dạng "tree-ish".

Bộ định danh cây-ish không thể được sử dụng làm cam kết

  1. <rev>:<path>, dẫn trực tiếp đến cây thư mục, không phải đối tượng cam kết. Ví dụ HEAD:subdirectory,.

  2. Định danh Sha1 của các đối tượng cây thư mục .


3
Đừng quên về stash@{0}. Tôi muốn biết nơi nào phù hợp với tất cả những điều này. Có những thứ khác giống như stash ( my-thing@{0}) không? Có phải kho chỉ là một <refname>?
Nate

Nó đã không được làm rõ ràng một cách rõ ràng rằng một định danh tree-ish dường như là một định danh cụ thể hơn một định danh commit-ish. Có lẽ tôi là lạ, nhưng đó là cách duy nhất hợp lý để giải thích nó IMO
Steven Lu

29

Lưu ý đối với người nói tiếng Anh [sic!] Không phải là bản ngữ: "-ish" là một hậu tố có thể được áp dụng cho một tính từ để biểu thị "có những phẩm chất như" hoặc "hơi" - xem tại http://chambers.co.uk / search /? query = ish & title = 21

Do đó "tree-ish" - giống như "tree" .... "commit-ish" - giống như "commit"

ví dụ: "Sao Hỏa xuất hiện giống như một ngôi sao màu đỏ" ("d" được nhân đôi!); "thức ăn trên đĩa không nóng, nhưng hơi ấm"

Tôi tin rằng điều này giúp giải thích "những gì là ..." tốt hơn, trong đó nó giải thích cách sử dụng ngôn ngữ.


Tôi luôn diễn giải "tree-ish" và "commit-ish" tương tự như khi nói "tiếng Thụy Điển" hoặc "tiếng Anh". Cách sử dụng mà bạn mô tả ít có ý nghĩa hơn đối với tôi vì dạng "ish" đó tạo ra một tính từ. Nhưng rev không phải là "giống như" một cái cây hoặc cam kết, nó một cây hoặc cam kết. Mặt khác, nếu bạn nghĩ "ish" là một hậu tố ngôn ngữ thì chúng có ý nghĩa hơn như là danh từ trên dòng lệnh, trong đó "tree-ish" là ngôn ngữ tạo thành danh từ. Tôi không biết cách giải thích nào là ý định của các tác giả, nhưng đó là cách tôi luôn thấy nó.
jmt

Tôi hiểu quan điểm của bạn, nhưng tôi chỉ tạo ấn tượng mà tôi có, với tư cách là một người nói tiếng Anh bản ngữ!
MikeW
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.