Commit-ish และ Tree-ish ใน Git คืออะไร?


117

คำถาม

อะไรคือตัวอย่างที่เฉพาะเจาะจงของการกระทำ-ish และ tree-ish ใน Git

คำถาม Stack Overflow "tree-ish หมายถึงอะไรในคอมไพล์" เกี่ยวข้องกับ tree-ish โดยเฉพาะ แต่ฉันต้องการทำความเข้าใจเพิ่มเติมเกี่ยวกับทั้งสองอย่าง

พื้นหลัง

การใช้งานในเอกสาร

เอกสาร Gitมีการอ้างถึง "comm-ish" และ "tree-ish" หลายรายการ ตัวอย่างเช่นหากคุณกำลังตรวจสอบซอร์สโค้ด 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

คำนิยาม

เอกสาร Git กำหนดสิ่งที่ "กระทำ-ish" และ "tree-ish" คือ :

<tree>

ระบุชื่อวัตถุต้นไม้

<commit>

ระบุชื่ออ็อบเจ็กต์คอมมิต

<tree-ish>

ระบุต้นไม้คอมมิตหรือแท็กชื่ออ็อบเจ็กต์ คำสั่งที่รับ<tree-ish> อาร์กิวเมนต์ในที่สุดต้องการดำเนินการกับ<tree>อ็อบเจ็กต์ แต่ dereferences โดยอัตโนมัติ<commit>และ<tag>อ็อบเจ็กต์ที่ชี้ไปที่ a <tree>.

<commit-ish>

ระบุชื่ออ็อบเจ็กต์คอมมิตหรือแท็ก คำสั่งที่ใช้<commit-ish> อาร์กิวเมนต์ในท้ายที่สุดต้องการที่จะทำงานบน<commit>วัตถุโดยอัตโนมัติ แต่ dereferences วัตถุจุดที่ว่า<tag><commit>

เอกสารไม่ชัดเจนเพียงพอ

แม้ว่าเอกสารข้างต้นจะระบุว่า "คอมมิต - อิช" และ "ทรี - อิช" คืออะไร แต่ฉันก็ยังพบว่ามันคลุมเครือและไม่ชัดเจนเกินไป

อะไรคือตัวอย่างที่เฉพาะเจาะจงของ "คอมมิต - อิช" และ "ทรี - อิช" และต่างกันอย่างไร

คำตอบ:


156

คำตอบสั้น ๆ (TL; DR)

นี่คือรายการทั้งหมดของตัวระบุการกระทำและโครงสร้างต้นไม้ (จากเอกสารประกอบการแก้ไข 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
----------------------------------------------------------------------

ตัวระบุ # 1-14 ล้วนเป็น "คอมมิต - ish" เนื่องจากทั้งหมดนำไปสู่คอมมิต แต่เนื่องจากคอมมิตชี้ไปที่แผนผังไดเร็กทอรีด้วยในที่สุดจึงนำไปสู่ ​​(ย่อย) ออบเจ็กต์แผนผังไดเร็กทอรีดังนั้นจึงสามารถใช้เป็น "tree -ish"

# 15 ยังสามารถใช้เป็น tree-ish เมื่ออ้างถึงไดเร็กทอรี (ย่อย) แต่ยังสามารถใช้เพื่อระบุไฟล์เฉพาะได้ เมื่อพูดถึงไฟล์ฉันไม่แน่ใจว่ายังถือว่าเป็น "tree-ish" อยู่หรือไม่หรือทำหน้าที่เหมือน "blob-ish" มากกว่า (Git หมายถึงไฟล์เป็น "blobs")

คำตอบยาว

Commits และ Directory Trees ใน Git

ในระดับต่ำสุด Git จะติดตามซอร์สโค้ดโดยใช้อ็อบเจ็กต์พื้นฐานสี่อย่าง:

  1. แท็กที่มีคำอธิบายประกอบซึ่งชี้ไปที่คอมมิต
  2. คอมมิตซึ่งชี้ไปที่แผนผังไดเร็กทอรีรูทของโปรเจ็กต์ของคุณ
  3. ต้นไม้ซึ่งเป็นไดเร็กทอรีและไดเร็กทอรีย่อย
  4. Blobs ซึ่งเป็นไฟล์

แต่ละออบเจ็กต์เหล่านี้มี ID แฮช sha1 ของตัวเองเนื่องจาก Linus Torvalds ได้ออกแบบ Git ให้เหมือนกับระบบไฟล์ที่ระบุแอดเดรสได้กล่าวคือไฟล์สามารถเรียกดูได้ตามเนื้อหาของมัน (sha1 IDs ถูกสร้างขึ้นจากเนื้อหาไฟล์) หนังสือ Pro Git แสดงแผนภาพตัวอย่างนี้ :

รูปที่ 9-3 จากหนังสือ Pro Git

Commit-ish กับ Tree-ish

คำสั่ง Git จำนวนมากสามารถยอมรับตัวระบุพิเศษสำหรับคอมมิตและโครงสร้างไดเร็กทอรี (ย่อย):

  • "Commit-ish" คือตัวระบุที่นำไปสู่อ็อบเจ็กต์คอมมิตในที่สุด ตัวอย่างเช่น,

    tag -> commit

  • "Tree-ish" คือตัวระบุที่นำไปสู่อ็อบเจ็กต์ tree (เช่นไดเร็กทอรี) ในที่สุด

    tag -> commit -> project-root-directory

เนื่องจากอ็อบเจ็กต์คอมมิตชี้ไปที่อ็อบเจ็กต์ไดเร็กทอรีทรีเสมอ (ไดเร็กทอรีรูทของโปรเจ็กต์ของคุณ) ตัวระบุใด ๆ ที่เป็น "คอมมิต - ish" ตามนิยามและ "tree-ish" ด้วย ในคำอื่น ๆระบุใด ๆ ที่นำไปสู่การกระทำวัตถุนอกจากนี้ยังสามารถนำมาใช้เพื่อนำไปสู่การ (ย่อย) วัตถุต้นไม้ไดเรกทอรี

แต่เนื่องจากออบเจ็กต์แผนผังไดเร็กทอรีไม่เคยชี้ไปที่คอมมิตในระบบการกำหนดเวอร์ชันของ Git จึงไม่สามารถใช้ตัวระบุทุกตัวที่ชี้ไปที่โครงสร้างไดเร็กทอรี (ย่อย) เพื่อชี้ไปที่คอมมิตได้ กล่าวอีกนัยหนึ่งชุดของตัวระบุ "คอมมิต" คือชุดย่อยที่เข้มงวดของชุดตัวระบุ "tree-ish"

ชุดของตัวระบุ tree-ish ที่ไม่สามารถใช้เป็น comm-ishได้

  1. <rev>:<path>ซึ่งนำไปสู่ไดเร็กทอรีทรีโดยตรงไม่คอมมิตอ็อบเจ็กต์ ตัวอย่างเช่นHEAD:subdirectory.

  2. ตัวระบุ Sha1 ของวัตถุแผนผังไดเรกทอรี


3
stash@{0}อย่าลืมเกี่ยวกับ ฉันอยากรู้ว่าตรงไหนที่เหมาะกับทั้งหมดนี้ มีสิ่งอื่น ๆ เช่นที่ซ่อน ( my-thing@{0}) หรือไม่? ที่ซ่อนเป็นเพียง<refname>?
เนท

ยังไม่มีการระบุอย่างชัดเจนว่าตัวระบุ tree-ish ดูเหมือนจะเป็นตัวระบุที่เฉพาะเจาะจงมากกว่าตัวระบุการกระทำ บางทีฉันอาจจะแปลก แต่นั่นเป็นวิธีเดียวที่สมเหตุสมผลในการอธิบาย IMO
Steven Lu

29

หมายเหตุสำหรับผู้พูด [sic!] ที่ไม่ใช่เจ้าของภาษาอังกฤษ: "-ish" เป็นคำต่อท้ายที่สามารถนำไปใช้กับคำคุณศัพท์เพื่อระบุว่า "มีคุณสมบัติเหมือน" หรือ "เล็กน้อย" - ดูhttp://chambers.co.uk / search /? แบบสอบถาม = ish & title = 21

ดังนั้น "tree-ish" - เหมือน "ต้นไม้" .... "กระทำ-ish" - เหมือน "กระทำ"

เช่น "ดาวอังคารดูเหมือนดาวสีแดง" ("d" เป็นสองเท่า!); "อาหารในจานไม่ร้อน แต่อุ่น"

ฉันเชื่อว่าสิ่งนี้ช่วยอธิบาย "อะไรคือ ... " ได้ดีกว่าซึ่งจะอธิบายการใช้ภาษา


ฉันมักตีความคำว่า "tree-ish" และ "comm-ish" ให้คล้ายคลึงกับการพูดว่า "Swedish" หรือ "English" การใช้งานที่คุณอธิบายไม่สมเหตุสมผลสำหรับฉันเพราะรูปแบบของ "ish" สร้างคำคุณศัพท์ แต่ rev ไม่ "เหมือน" ต้นไม้หรือคอมมิตมันเป็นต้นไม้หรือคอมมิต ในทางกลับกันถ้าคุณคิดว่า "ish" เป็นคำต่อท้ายภาษาก็จะมีความหมายมากกว่าในฐานะคำนามในบรรทัดคำสั่งโดยที่ "tree-ish" เป็นภาษาที่สร้างคำนาม ฉันไม่รู้ว่าการตีความใดเป็นเจตนาของผู้เขียน แต่นั่นเป็นสิ่งที่ฉันเห็นมาตลอด
jmt

ฉันเห็นประเด็นของคุณ แต่ฉันแค่ให้ความรู้สึกที่ฉันมีในฐานะเจ้าของภาษา!
MikeW
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.