tree-ish หมายถึงอะไรใน Git?


122

git archiveฉันสับสนมากเกี่ยวกับวิธีการใช้

ฉันมีที่เก็บ git พร้อมโฟลเดอร์ Foo , BarและBazที่ระดับบนสุด ฉันต้องการส่งออกโฟลเดอร์Fooด้วยวิธี SVN-ish เพื่อการทดสอบการใช้งานอย่างรวดเร็ว

ฉันได้เรียนรู้ว่าฉันสามารถใช้git-archiveในวิธีการส่งออก SVN-ishได้

แต่นี่คือสิ่งต่อไปนี้ใช้งานได้ดี:

git archive master | tar -x -C ~/destination

ส่งผลให้โฟลเดอร์Foo , Bar , Bazในโฟลเดอร์ปลายทาง

อย่างไรก็ตามสิ่งต่อไปนี้จะเกิดข้อผิดพลาดกับfatal not a valid object name:

git archive master/foo | tar -x -C ~/destination

เอกสารประกอบ

ดูเป็นบทสรุปของgit archiveโปรแกรมฉันเห็นว่ามันสามารถใช้<tree-ish> [path]เป็นพารามิเตอร์ได้ (สรุปสรุปไปยังส่วนที่เกี่ยวข้อง):

git archive <tree-ish> [path...]

ถ้า master/foo ไม่ tree-ishแล้วคืออะไร?


2
master:fooเป็นต้นไม้-ish แต่คุณใช้ดีกว่าที่ฉันmaster foo <tree-ish> <path>
Jakub Narębski

1
ฉันตีความ <tree-ish> เป็นและคำคุณศัพท์ของ [path] นั่นคือสิ่งที่ฉันผิดพลาด และตัวอย่างทั้งหมดที่ฉันเห็นนั้นใช้เฉพาะส่วน <tree-ish> ของคำสั่งดังนั้นฉันจึงคิดผิดว่าพวกเขาใช้เส้นทาง '<tree-ish> โอ้ความหมาย :)
dkinzer

2
ที่เกี่ยวข้อง: คอมมิต-ish และ tree-ish ใน Git คืออะไร? .

3
ฉันมีปัญหากับคำถามนี้เพราะชื่อถามเกี่ยวกับสิ่งที่ tree-ish อยู่ในคอมไพล์ แต่แล้วมันก็เริ่มต้นและดูเหมือนจะเกี่ยวกับคำสั่งบางอย่างเป็นหลัก นอกจากนี้คำตอบที่ยอมรับดูเหมือนจะไม่ได้ระบุถึงความหมายของคำว่า tree-ish อย่างแน่นอน ต้องเปลี่ยนชื่อคำถามหรือคำถามต้องเปลี่ยน ฉันขอแนะนำว่าควรปรับชื่อเรื่องให้เข้ากับคำถามที่เป็นประเด็นเกี่ยวกับเรื่องนี้ได้ดีขึ้นและคำตอบที่ยอมรับคืออะไร หรืออาจจะเปลี่ยนคำตอบที่ยอมรับว่าชื่อคำถามคืออะไร หรือคำตอบควรอยู่ที่ชื่อคำถาม
Charlie Parker

@CharlieParker เห็นได้ชัดว่าหน้าคนสำหรับgit archiveคำสั่งไม่ได้อ้างถึง tree-ish อีกต่อไป แต่เมื่อฉันถามคำถามนี้พวกเขาทำ และเกี่ยวกับคำตอบที่ยอมรับ; ในเวลานั้นไม่มีใครสนใจที่จะตอบคำถาม สองปีต่อมามีการโพสต์คำตอบอื่น
dkinzer

คำตอบ:


167

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

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

ในกรณีของโปสเตอร์ต้นฉบับfoo คือไดเร็กทอรีที่เขาต้องการระบุ วิธีที่ถูกต้องในการระบุไดเร็กทอรี (ย่อย) ใน Git คือการใช้ไวยากรณ์ "tree-ish" (รายการ # 15 จากเอกสารการแก้ไข Git ):

<rev>:<path>เช่นHEAD:README, :README,master:./README

คำต่อท้าย:ตามด้วยพา ธ ตั้งชื่อหยดหรือทรีตามเส้นทางที่กำหนดในอ็อบเจ็กต์ tree-ish ที่ตั้งชื่อโดยส่วนก่อนโคลอน

ดังนั้นในคำอื่น ๆ ที่เป็นไวยากรณ์ที่ถูกต้องไม่ได้master:foomaster/foo

"Tree-ish" อื่น ๆ (Plus Commit-ish)

นี่คือรายการที่สมบูรณ์ของตัวระบุกระทำ-ish และต้นไม้ ish (จากเอกสารการแก้ไข Git , ขอบคุณที่ LopSae สำหรับการชี้ออก ):

----------------------------------------------------------------------
|    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, :README, master:./README
----------------------------------------------------------------------
|         Tree-ish?         |                Examples
----------------------------------------------------------------------
| 16. :<n>:<path>           | :0:README, :README
----------------------------------------------------------------------

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

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

คำตอบยาว

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

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

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

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

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

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

    tag -> commit

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

    tag -> commit -> project-root-directory

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

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

ตามที่อธิบายไว้ในเอกสาร ( ขอบคุณ Trebor ที่ช่วยฉันค้นหา ):

<tree>

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

<commit>

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

<tree-ish>

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

<commit-ish>

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

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

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

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


รายการ 16 บนโต๊ะของคุณล่ะ? หมายความว่าคุณไม่แน่ใจว่าเป็นต้นไม้หรือไม่? 0 หมายถึงสถานะการผสานและแนวคิดนี้ใช้กับ blobs เท่านั้นเนื่องจากดัชนีไม่มีแม้แต่ไดเรกทอรี ดู: stackoverflow.com/a/25806452/895245 ดังนั้นคำถามจึงลงมาที่: ไอชอลทั้งหมดเป็นไอเอชต้นไม้หรือไม่? เท่าที่ฉันสามารถบอกได้ว่า: หน้าทั้งหมดที่ใช้<tree-ish>ยอมรับทั้งสองอย่างและman gitrevisionsกำหนด: trees ("directories of files").
Ciro Santilli 郝海东冠状病六四事件法轮功

โปรดทราบgit-archiveว่าต้องใช้เวลา<tree-ish>แต่ไม่อนุญาตไฟล์<sha1>. ดังนั้นฉันเดาว่าควรขอไฟล์<tree-ish-ish>. stackoverflow.com/a/12073669/680464
juanitogan

อย่างไรก็ตามฉันสงสัยว่าจะเกิดอะไรขึ้นเมื่อฉันใช้ <rev>: (โดยไม่มีเส้นทางใด ๆ มันใช้งานได้ตามที่พยายาม - แต่ฉันไม่พบส่วนที่เกี่ยวข้องในเอกสารประกอบ
Martin Vejmelka

49

Tree-ish เป็นวิธีการตั้งชื่อต้นไม้เฉพาะซึ่งอาจเป็นอย่างใดอย่างหนึ่งต่อไปนี้:

  • การอ้างอิงเช่น:
    • ศีรษะ
    • แท็ก
    • ชื่อสาขา
    • ชื่อสาขาพร้อมรีโมทเช่น origin/somebranch
  • กัญชา
  • แฮชสั้น ๆ

ด้านบนของที่ใด ๆ ข้างต้นสามารถผนวกกับ,^ ~การอ้างอิงยังสามารถใช้@{}สัญกรณ์สำหรับคุณสมบัติเพิ่มเติมบางอย่าง:

  • HEAD^หรือHEAD^1จะแก้ไขให้กับผู้ปกครองคนแรกของ HEAD
  • HEAD^2 จะแก้ไขให้ผู้ปกครองคนที่สอง
  • HEAD^3จะแก้ปัญหาให้กับผู้ปกครองที่สามและอื่น ๆ ซึ่งเป็นของหายากมากขึ้นและสินค้าของ ผสานกับกลยุทธ์ของปลาหมึก
  • HEAD~หรือHEAD~1จะแก้ปัญหาให้กับผู้ปกครองคนแรกของหัวหน้า
  • HEAD~2จะแก้ไขเป็นผู้ปกครองคนแรกของผู้ปกครองคนแรกของ HEAD ซึ่งจะเหมือนกับHEAD^^
  • HEAD@{0} จะแก้ไขเป็น HEAD ปัจจุบัน
  • HEAD@{1}จะแก้ไขไปยังส่วนหัวก่อนหน้า สิ่งนี้สามารถใช้ได้โดยการอ้างอิงเท่านั้นเนื่องจากใช้ประโยชน์จากบันทึกการอ้างอิง ในกรณีของการคอมHEADมิตทุกครั้งการรวมการชำระเงินจะเปลี่ยนค่าของ HEAD และเพิ่มลงในบันทึก git reflog HEADจะแสดงบันทึกการอ้างอิงซึ่งคุณสามารถดูการเคลื่อนไหวทั้งหมดของ HEAD และสิ่ง@{1}ที่จะแก้ไขได้อย่างถูกต้อง

HEAD@{2}~3ส่วนใหญ่ข้างต้นสามารถนำมารวมกันต่อไปตราบใดที่มันทำให้ความรู้สึกในพื้นที่เก็บข้อมูลของคุณตัวอย่างเช่น: somebranch^2~4, c00e66e~4^2, anotherbranch~^~^~^,

ดังนั้นสิ่งที่อธิบายไว้ข้างต้นและการรวมกันจึงเป็นสิ่งที่มีความหมายในเอกสารประกอบว่า tree-ish ซึ่งเป็นเพียงวิธีการบอกว่าต้นไม้ (หรือการแก้ไข) ใดเป็นสิ่งที่ควรใช้สำหรับคำสั่ง git ส่วนใหญ่

ข้อมูลเพิ่มเติมในการทบทวนการคัดเลือกในหนังสือเล่ม Git


1
คำตอบนี้อธิบายถึงการแก้ไขโดยทั่วไป (คอมมิต - อิช) และพลาดกรณีสำคัญ: master:path/to/directoryซึ่งเป็นทรีไอเอช แต่ไม่ใช่คอมมิต - อิช Cupcake ทำให้ชัดเจนขึ้น
Ciro Santilli 郝海东冠状病六四事件法轮功

11

คุณอาจต้องการ

git archive master foo | tar -x -C ~/destination

นิพจน์master/fooไม่สมเหตุสมผล: masterเป็นชื่อสาขาและfooเป็นชื่อไดเร็กทอรีตามที่ฉันคิดไว้

แก้ไข : (ลบลิงค์เสียดูความคิดเห็น)


ไม่พบคำว่า "ต้นไม้" ในลิงก์ "Git Treeishes" อีกต่อไป FYI
Robert

Treeish โดยทั่วไปหมายถึงแผนผังการแก้ไขไม่ใช่การจัดวางไดเร็กทอรี
Jürgen Strobel

6
@ JürgenStrobel: นั่นไม่เป็นความจริง มันไม่ได้อ้างถึงทั้งสองอย่าง - ในอดีตกาลเนื่องจากคำนี้ไม่ได้ใช้อีกต่อไปในเอกสารประกอบเวอร์ชันปัจจุบัน (นั่นเป็นสาเหตุที่ทำให้ลิงก์เสีย) เดิมต้นไม้เรียกสิ่งที่สามารถแก้ไขได้กับวัตถุต้นไม้ในที่เก็บอ็อบเจ็กต์ของคอมไพล์ สิ่งนี้รวมถึงข้อกำหนดการคอมมิชชันใด ๆ เนื่องจากแต่ละคอมมิตอ้างถึงอ็อบเจ็กต์ต้นไม้เดียว วัตถุต้นไม้มีข้อมูลเกี่ยวกับต้นไม้ไดเรกทอรีนี้กระทำ - ดูส่วนที่เกี่ยวกับวัตถุคอมไพล์ใน "โปร Git"สำหรับรายละเอียด
Sven Marnach

6

สำหรับคำจำกัดความของ<tree-ish>และ<commit-ish>ดูman page git (1) คุณจะต้องค้นหาคำศัพท์ โดยทั่วไป<tree-ish>หมายถึงการอ้างอิงไปยังวัตถุ git tree แต่ถ้าคุณส่งผ่านประเภทของวัตถุที่อ้างอิงถึงต้นไม้ (เช่นการกระทำหรือกิ่งก้าน) git จะใช้ต้นไม้ที่อ้างอิงโดยอัตโนมัติ


และgitrevisions(7).
Xiong Chiamiov

0

ฉันเป็นมือใหม่ในการควบคุมแหล่งที่มาและคอมไพล์ นี่คือสิ่งที่ฉันรู้ ทรีคือโครงสร้างของไฟล์ในที่เก็บ คล้ายกับไดเร็กทอรีในระบบไฟล์ดู - เครื่องมือ git ใดสร้างมุมมองแบบทรีนี้

Tree-ish แปลว่าเหมือนต้นไม้ อ้างอิงถึงส่วนหนึ่งหรือการกระทำของต้นไม้ คุณสามารถอ้างอิงคอมมิตโดยใช้อย่างใดอย่างหนึ่งต่อไปนี้: แฮช SHA-1 ทั้งหมดหรือบางส่วนของคอมมิต, ตัวชี้ HEAD, การอ้างอิงสาขา, การอ้างอิงแท็ก อีกวิธีหนึ่งใช้วิธีการใด ๆ ที่กล่าวถึงร่วมกับบรรพบุรุษหรือผู้ปกครองของการกระทำ ตัวอย่างบรรพบุรุษ: ใส่คำอธิบายภาพที่นี่


0

จากGit Glossary tree-ish คือ "A tree object หรือ an object that can be recursively dereferenced to a tree object" คอมมิต, HEAD และแท็กเป็นตัวอย่างของอ็อบเจกต์แบบต้นไม้

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