Apa itu commit-ish dan tree-ish di Git?

117

Pertanyaan

Apa contoh spesifik dari commit-ish dan tree-ish di Git?

Pertanyaan Stack Overflow "Apa arti tree-ish di git?" berurusan dengan pohon-ish secara khusus, tetapi saya ingin memahami lebih banyak tentang keduanya .

Latar Belakang

Penggunaan dalam Dokumentasi

Dokumentasi Git membuat beberapa referensi ke "commit-ish" dan "tree-ish". Misalnya, jika Anda memeriksa kode sumber 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

dan

$ 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

Definisi

Dokumentasi Git mendefinisikan apa itu "commit-ish" dan "tree-ish" :

<tree>

Menunjukkan nama objek pohon.

<commit>

Menunjukkan nama objek komit.

<tree-ish>

Menunjukkan pohon, komit atau nama objek tag. Perintah yang mengambil <tree-ish> argumen pada akhirnya ingin beroperasi pada <tree>objek tetapi secara otomatis referensi <commit>dan <tag>objek yang mengarah ke a <tree>.

<commit-ish>

Menunjukkan nama objek komit atau tag. Perintah yang mengambil <commit-ish> argumen pada akhirnya ingin beroperasi pada <commit>objek tetapi secara otomatis mendereferensi <tag>objek yang mengarah ke a <commit>.

Dokumentasi tidak Cukup Jelas

Meskipun dokumentasi di atas mendefinisikan apa itu "commit-ish" dan "tree-ish", saya masih menganggapnya terlalu kabur dan tidak jelas.

Apa contoh spesifik dari "commit-ish" dan "tree-ish", dan apa perbedaannya satu sama lain?

Komunitas
sumber

Jawaban:

156

Jawaban Singkat (TL; DR)

Berikut adalah daftar lengkap pengenal commit-ish dan tree-ish (dari dokumentasi revisi 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
----------------------------------------------------------------------

Pengidentifikasi # 1-14 semuanya "commit-ish", karena semuanya mengarah ke komit, tetapi karena komit juga menunjuk ke pohon direktori, mereka semua pada akhirnya mengarah ke (sub) objek pohon direktori, dan karena itu juga dapat digunakan sebagai "pohon -ish ".

# 15 juga dapat digunakan sebagai pohon-ish ketika merujuk ke direktori (sub), tetapi juga dapat digunakan untuk mengidentifikasi file tertentu. Ketika merujuk ke file, saya tidak yakin apakah itu masih dianggap "tree-ish", atau apakah bertindak lebih seperti "blob-ish" (Git menyebut file sebagai "blob").

Jawaban Panjang

Komit dan Pohon Direktori di Git

Pada level terendahnya, Git melacak kode sumber menggunakan empat objek fundamental:

  1. Tag beranotasi, yang mengarah ke komit.
  2. Komit, yang mengarah ke pohon direktori root proyek Anda.
  3. Pohon, yaitu direktori dan subdirektori.
  4. Blob, yang merupakan file.

Masing-masing objek ini memiliki ID hash sha1 sendiri, karena Linus Torvalds mendesain Git seperti sistem file beralamat konten , yaitu file dapat diambil berdasarkan isinya (ID sha1 dihasilkan dari konten file). Buku Pro Git memberikan diagram contoh ini :

Gambar 9-3 dari buku Pro Git

Commit-ish vs Tree-ish

Banyak perintah Git dapat menerima pengenal khusus untuk komit dan (sub) pohon direktori:

  • "Commit-ish" adalah pengidentifikasi yang pada akhirnya mengarah ke objek komit. Sebagai contoh,

    tag -> commit

  • "Tree-ish" adalah pengenal yang pada akhirnya mengarah ke objek pohon (yaitu direktori).

    tag -> commit -> project-root-directory

Karena objek komit selalu menunjuk ke objek pohon direktori (direktori akar proyek Anda), setiap pengenal yang "komit-ish", menurut definisi, juga "pohon-ish". Dengan kata lain, pengenal apa pun yang mengarah ke objek komit juga bisa digunakan untuk mengarahkan ke objek pohon (sub) direktori .

Tetapi karena objek pohon direktori tidak pernah menunjuk ke komit dalam sistem versi Git, tidak setiap pengenal yang menunjuk ke pohon (sub) direktori juga bisa digunakan untuk menunjuk ke komit. Dengan kata lain, himpunan pengenal "commit-ish" adalah himpunan bagian ketat dari himpunan pengenal "tree-ish".

Kumpulan pengenal pohon-ish yang tidak dapat digunakan sebagai komit-ish adalah

  1. <rev>:<path>, yang mengarah langsung ke pohon direktori, bukan objek komit. Misalnya HEAD:subdirectory,.

  2. Pengenal Sha1 dari objek pohon direktori .


sumber
3
Jangan lupakan stash@{0}. Saya ingin tahu di mana yang cocok dengan semua ini. Apakah ada hal lain seperti simpanan ( my-thing@{0})? Apakah simpanan itu hanya a <refname>?
Nate
Belum dijelaskan secara eksplisit bahwa pengenal tree-ish tampaknya merupakan pengenal yang lebih spesifik daripada pengenal commit-ish. Mungkin saya aneh tapi itulah satu-satunya cara yang masuk akal untuk menjelaskannya IMO
Steven Lu
29

Catatan untuk penutur [sic!] Bukan penutur asli bahasa Inggris: "-ish" adalah sufiks yang dapat diterapkan pada kata sifat untuk menunjukkan "memiliki kualitas seperti" atau "sedikit" - lihat http://chambers.co.uk / search /? query = ish & title = 21

Karenanya "tree-ish" - seperti "tree" .... "commit-ish" - seperti "commit"

misalnya "Mars tampak seperti bintang kemerahan" ("d" digandakan!); "makanan di piring tidak panas, tapi hangat"

Saya percaya bahwa ini membantu menjelaskan "apa yang ..." dengan lebih baik, karena menjelaskan penggunaan bahasa.

MikeW
sumber
Saya selalu menafsirkan "tree-ish" dan "commit-ish" untuk dianalogikan dengan "Swedish" atau "English". Penggunaan yang Anda gambarkan kurang masuk akal bagi saya karena bentuk "ish" itu menciptakan kata sifat. Tapi rev bukanlah "seperti" pohon atau komit, itu adalah pohon atau komit. Di sisi lain, jika Anda menganggap "ish" sebagai sufiks bahasa maka mereka lebih masuk akal sebagai kata benda pada baris perintah, di mana "pohon-ish" adalah bahasa yang membentuk kata benda. Saya tidak tahu interpretasi mana yang menjadi tujuan penulis, tetapi itulah cara saya selalu melihatnya.
jmt
Saya mengerti maksud Anda, tetapi saya hanya memberikan kesan yang saya miliki, sebagai penutur asli bahasa Inggris!
MikeW