Anda melihat dokumentasi Git mengatakan hal-hal seperti
Cabang harus sepenuhnya digabung dalam KEPALA.
Tapi apa HEAD
sebenarnya Git ?
Anda melihat dokumentasi Git mengatakan hal-hal seperti
Cabang harus sepenuhnya digabung dalam KEPALA.
Tapi apa HEAD
sebenarnya Git ?
Jawaban:
Anda dapat menganggap HEAD sebagai "cabang saat ini". Ketika Anda beralih cabang dengan git checkout
, revisi HEAD berubah untuk menunjuk ke ujung cabang baru.
Anda dapat melihat apa yang ditunjuk HEAD dengan melakukan:
cat .git/HEAD
Dalam kasus saya, hasilnya adalah:
$ cat .git/HEAD
ref: refs/heads/master
Dimungkinkan HEAD untuk merujuk pada revisi spesifik yang tidak terkait dengan nama cabang. Situasi ini disebut HEAD terpisah .
Mengutip orang lain :
Head hanyalah referensi ke objek commit. Setiap kepala memiliki nama (nama cabang atau nama tag, dll). Secara default, ada kepala di setiap repositori yang disebut master. Repositori dapat berisi sejumlah kepala. Pada waktu tertentu, satu kepala dipilih sebagai "kepala saat ini." Kepala ini alias KEPALA, selalu dalam huruf kapital ".
Perhatikan perbedaan ini: "head" (huruf kecil) mengacu pada salah satu dari head yang disebutkan dalam repositori; "KEPALA" (huruf besar) merujuk secara eksklusif ke kepala yang sedang aktif. Perbedaan ini sering digunakan dalam dokumentasi Git.
Sumber bagus lain yang dengan cepat membahas cara kerja internal git (dan karenanya pemahaman yang lebih baik tentang kepala / kepala) dapat ditemukan di sini . Referensi (ref :) atau kepala atau cabang dapat dianggap seperti catatan post-it yang tertempel pada komit dalam riwayat komit. Biasanya mereka menunjuk ke ujung serangkaian komit, tetapi mereka dapat dipindahkan dengan git checkout
atau lainnya git reset
.
git checkout HEAD~2
), yang bukan id komit dari kepala yang dikenal. Lihat artikel di eagain.net/articles/git-for-computer-scientists untuk penjelasan yang lebih mendalam.
git revert
bukan contoh yang baik untuk memindahkan cabang agar tidak berada di ujung, karena git revert
hanya membuat beberapa komitmen baru dan masih meninggalkan cabang saat ini di ujung (baru).
commit
, reset
s, dll.
Saya merekomendasikan definisi ini dari pengembang github Scott Chacon [ referensi video ]:
Kepala adalah cabang Anda saat ini. Ini adalah referensi simbolis. Ini adalah referensi ke cabang. Anda selalu memiliki KEPALA, tetapi KEPALA akan menunjuk ke salah satu petunjuk ini, ke salah satu cabang di mana Anda berada. Ini adalah induk dari komit Anda berikutnya. Inilah yang seharusnya menjadi yang terakhir diperiksa ke dalam direktori kerja Anda ... Ini adalah kondisi terakhir yang diketahui dari direktori kerja Anda.
Seluruh video akan memberikan pengantar yang adil untuk seluruh sistem git jadi saya juga menyarankan Anda untuk menonton semuanya jika punya waktu.
KEPALA hanyalah pointer khusus yang menunjuk ke cabang lokal Anda saat ini.
Dari buku Pro Git , bab 3.1 Git Branching - Branches in a Singkatnya , di bagian Membuat Cabang Baru :
Apa yang terjadi jika Anda membuat cabang baru? Nah, melakukan hal itu menciptakan pointer baru bagi Anda untuk bergerak. Katakanlah Anda membuat cabang baru yang disebut pengujian. Anda melakukan ini dengan perintah git branch:
$ git branch testing
Ini menciptakan pointer baru pada komit yang sama dengan yang Anda gunakan saat ini
Bagaimana Git tahu cabang apa yang saat ini Anda gunakan? Itu membuat pointer khusus yang disebut HEAD. Perhatikan bahwa ini sangat berbeda dari konsep HEAD di VCS lain yang mungkin Anda gunakan, seperti Subversion atau CVS. Di Git, ini adalah penunjuk ke cabang lokal tempat Anda saat ini. Dalam hal ini, Anda masih menguasai. Perintah git branch hanya membuat cabang baru - itu tidak beralih ke cabang itu.
34ac2
contoh di atas, sekarang HEAD akan menunjuk komit itu dan itu disebut HEAD terpisah. Dalam keadaan ini, Anda dapat membuat perubahan, bereksperimen, dan melakukan perubahan juga, tetapi begitu Anda checkout cabang lain, Anda akan kehilangan semua perubahan Anda, kecuali tentu saja Anda membuat cabang baru.
git log
dan mendapatkan sesuatu seperti commit ad0265... HEAD -> foo ...
itu berarti foo
cabang adalah referensi untuk melakukan id ad0265
. Melakukan checkout dari referensi teks foo
bukan kepala terpisah. Melakukan checkout pada id komit ad0265
akan menghasilkan kepala yang terpisah. Mungkin saya kehilangan beberapa kehalusan dari apa yang Anda komunikasikan. Saya harap tembok teks ini membantu menemukan di mana saya terhilang.
Dengan asumsi itu bukan kasus khusus yang disebut "KEPALA terlepas", maka, sebagaimana dinyatakan dalam buku O'Reilly Git, edisi ke-2, hal.69, HEAD
berarti:
HEAD
selalu merujuk pada komit terbaru di cabang saat ini. Saat Anda mengganti cabang,HEAD
diperbarui untuk merujuk pada komit terbaru cabang baru.
begitu
HEAD
adalah "tip" dari cabang saat ini .
Perhatikan bahwa kita dapat menggunakan HEAD
untuk merujuk ke komit terbaru, dan menggunakan HEAD~
sebagai komit sebelum tip, dan HEAD~~
atau HEAD~2
sebagai komit lebih awal, dan sebagainya.
Ada kesalahpahaman, mungkin halus, tetapi penting dalam sejumlah jawaban ini. Saya pikir saya akan menambahkan jawaban saya untuk menjernihkannya.
Apa
HEAD
?
HEAD
adalah referensi simbolis yang menunjukkan ke mana pun Anda berada dalam riwayat komit Anda. Ini mengikuti Anda ke manapun Anda pergi, apa pun yang Anda lakukan, seperti bayangan. Jika Anda membuat komitmen, HEAD
akan pindah. Jika Anda checkout sesuatu, HEAD
akan pindah. Apa pun yang Anda lakukan, jika Anda telah pindah ke suatu tempat baru dalam sejarah komit Anda, HEAD
telah pindah bersama Anda. Untuk mengatasi satu kesalahpahaman umum: Anda tidak dapat melepaskan diri dariHEAD
. Bukan itu kondisi KEPALA yang terpisah. Jika Anda menemukan diri Anda berpikir: "oh tidak, saya dalam kondisi HEAD terpisah! Saya telah kehilangan HEAD saya!" Ingat, ini KEPALA Anda. KEPALA adalah kamu. Anda belum terlepas dari KEPALA, Anda dan KEPALA Anda telah terlepas dari sesuatu yang lain.
HEAD
dapat menunjuk ke sebuah komit, ya, tetapi biasanya tidak. Izinkan saya mengatakan itu lagi. Biasanya HEAD
tidak menunjuk ke komit. Itu menunjuk ke referensi cabang. Itu melekat pada cabang itu, dan ketika Anda melakukan hal-hal tertentu (misalnya, commit
atau reset
), cabang terlampir akan bergerak bersama HEAD
. Anda dapat melihat apa yang menunjuk dengan melihat di bawah tenda.
cat .git/HEAD
Biasanya Anda akan mendapatkan sesuatu seperti ini:
ref: refs/heads/master
Terkadang Anda akan mendapatkan sesuatu seperti ini:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
Itulah yang terjadi ketika HEAD
menunjuk langsung ke sebuah komit. Ini disebut HEAD terpisah, karena HEAD
menunjuk ke sesuatu selain referensi cabang. Jika Anda membuat komitmen dalam kondisi ini master
, tidak lagi terikat HEAD
, tidak akan lagi bergerak bersama Anda. Tidak masalah di mana komit itu berada. Anda bisa berada di komit yang sama dengan cabang master Anda, tetapi jika HEAD
menunjuk ke komit daripada cabang, komit itu terlepas dan komit baru tidak akan dikaitkan dengan referensi cabang.
Anda dapat melihat ini secara grafis jika Anda mencoba latihan berikut. Dari repositori git, jalankan ini. Anda akan mendapatkan sesuatu yang sedikit berbeda, tetapi bit kunci mereka akan ada di sana. Ketika saatnya untuk checkout komit secara langsung, gunakan saja hash singkat apa pun yang Anda dapatkan dari output pertama (ini dia a3c485d
).
git checkout master
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD -> master)
git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD, master)
OK, jadi ada perbedaan kecil dalam output di sini. Memeriksa komit secara langsung (bukan cabang) memberi kita koma alih-alih panah. Bagaimana menurut Anda, apakah kita dalam kondisi KEPALA yang terpisah? KEPALA masih merujuk pada revisi tertentu yang dikaitkan dengan nama cabang. Kita masih di cabang utama, bukan?
Sekarang coba:
git status
# HEAD detached at a3c485d
Nggak. Kami dalam kondisi 'HEAD terlepas'.
Anda dapat melihat representasi (HEAD -> branch)
vs (HEAD, branch)
dengan yang sama git log -1
.
HEAD
apakah kamu Itu menunjuk pada apa pun yang Anda periksa, di mana pun Anda berada. Biasanya itu bukan komit, itu adalah cabang. Jika HEAD
memang menunjuk ke komit (atau tag), bahkan jika itu komit (atau tag) yang sama yang ditunjuk oleh cabang, Anda (dan HEAD
) telah terlepas dari cabang itu. Karena Anda tidak memiliki cabang yang melekat pada Anda, cabang tidak akan mengikuti Anda saat Anda membuat komitmen baru. HEAD
Namun, akan.
.git/HEAD
adalah apa yang dianggap perangkat lunak HEAD.
HEAD
mengacu pada komit saat ini yang ditunjuk oleh copy pekerjaan Anda, yaitu komit yang saat ini telah Anda periksa. Dari dokumentasi Linux Kernel resmi tentang menentukan revisi Git :
HEAD
memberi nama komit tempat Anda mendasarkan perubahan di pohon kerja.
Namun, perlu diketahui bahwa dalam versi 1.8.4 Git yang akan datang, @
juga dapat digunakan sebagai singkatan untuk HEAD
, seperti dicatat oleh kontributor Git Junio C Hamano dalam blog Git Blame-nya :
Alih-alih mengetik "HEAD", Anda dapat mengatakan "@" sebagai gantinya, misalnya "git log @".
Pengguna Stack Overflow VonC juga menemukan beberapa informasi menarik tentang mengapa @
dipilih sebagai singkatan dalam jawaban untuk pertanyaan lain .
Yang juga menarik, di beberapa lingkungan tidak perlu HEAD
menggunakan huruf besar, khususnya dalam sistem operasi yang menggunakan sistem file case-insensitive, khususnya Windows dan OS X.
Lihatlah Membuat dan bermain dengan cabang
HEAD sebenarnya adalah file yang isinya menentukan di mana variabel HEAD merujuk:
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
Dalam repositori ini, isi file HEAD merujuk ke file kedua bernama ref / kepala / master . File refs / heads / master berisi hash dari commit terbaru pada cabang master.
Hasilnya adalah HEAD menunjuk ke komit cabang utama dari file .git / refs / heads / master .
Saya hanya ingin menjelaskan beberapa hal dalam jawaban yang diterima Greg Hewgil. Menurut Panduan Saku Git
Cabang:
cabang itu sendiri didefinisikan sebagai semua titik yang dapat dijangkau dalam grafik komit dari komit yang dinamai ("tip" cabang).
KEPALA: Jenis khusus Ref
KEPALA ref khusus menentukan cabang apa yang Anda ...
Referensi
Git mendefinisikan dua jenis referensi, atau disebut pointer, yang disebut "referensi":
- Ref sederhana, yang menunjuk langsung ke ID objek (biasanya komit atau tag)
- Ref simbolik (atau symref), yang menunjuk ke ref lain (baik simbolik atau sederhana)
Seperti yang disebutkan Greg, KEPALA bisa berada dalam "keadaan terpisah". Jadi KEPALA bisa berupa ref sederhana (untuk KEPALA terpisah) atau symref.
jika KEPALA adalah ref simbolis untuk cabang yang ada, maka Anda "pada" cabang itu. Jika, di sisi lain, KEPALA adalah ref sederhana yang secara langsung memberi nama komit dengan ID SHA-1-nya, maka Anda tidak "di" cabang apa pun, melainkan dalam mode "terlepas kepala", yang terjadi ketika Anda memeriksa beberapa sebelumnya berkomitmen untuk memeriksa.
Saya pikir 'KEPALA' adalah saat ini memeriksa komit. Dengan kata lain 'KEPALA' menunjuk ke komit yang saat ini diperiksa.
Jika Anda baru saja mengkloning dan tidak memeriksa, saya tidak tahu apa artinya, mungkin beberapa lokasi tidak valid.
master
cabang - jadi HEAD akan menunjuk ke master.
master
, tetapi tidak selalu. Lihatremote set-head
remote set-head
, yang hanya berdampak pada cabang default lokal, dan tidak akan mengubah default di server.
Kepala menunjuk ke ujung cabang yang sedang diperiksa.
Di repositori Anda, ada folder .git. Buka file di lokasi ini: .git \ refs \ head. Kode (hasa-1 hash) dalam file itu (master dalam kebanyakan kasus) akan menjadi komit terbaru, yaitu yang terlihat pada output perintah git log
. Info lebih lanjut tentang folder .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html
git reset HEAD^
, dan kemudian komit terbaru (bekas tip) tidak lagi menunjuk ke ujung cabang.
Setelah membaca semua jawaban sebelumnya, saya masih ingin lebih jelas. Blog ini di situs git resmi http://git-scm.com/blog memberi saya apa yang saya cari:
HEAD in Git adalah pointer ke referensi cabang saat ini, yang pada gilirannya adalah pointer ke komit terakhir yang Anda buat atau komit terakhir yang diperiksa ke direktori kerja Anda. Itu juga berarti itu akan menjadi induk dari komit berikutnya yang Anda lakukan. Ini umumnya paling sederhana untuk dipikirkan karena HEAD adalah snapshot dari commit terakhir Anda.
HEAD
bukan komitmen; itu menunjuk ke satu.
checkout HEAD^
, sekarang HEAD bahkan tidak menunjuk ke snapshot komit terakhir pada cabang mana pun.
commit
, merge
, rebase
, log
, dll Tapi konseptual mungkin "(pointer ke) posisi saat" adalah ringkasan yang baik.
Rasanya seperti itu HEAD
hanya tag untuk komit terakhir yang Anda periksa.
Ini bisa menjadi ujung cabang tertentu (seperti "master") atau beberapa komit di antara cabang ("head terpisah")
Selain semua definisi, hal yang melekat dalam pikiran saya adalah, ketika Anda membuat komit, GIT membuat objek komit dalam repositori. Objek komit harus memiliki orang tua (atau beberapa orang tua jika itu adalah gabungan komit). Sekarang, bagaimana git mengetahui induk dari commit saat ini? Jadi KEPALA adalah pointer ke (referensi) komit terakhir yang akan menjadi induk dari komit saat ini.
Keduanya mungkin membingungkan Anda:
kepala
Menunjuk referensi yang diberi nama cabang yang baru saja dikirimkan. Kecuali Anda menggunakan referensi paket, head biasanya disimpan dalam $ GIT_DIR / refs / heads /.
KEPALA
Cabang saat ini, atau pohon kerja Anda biasanya dihasilkan dari pohon KEPALA menunjuk. KEPALA harus mengarah ke kepala, kecuali Anda menggunakan KEPALA terpisah.
Lihatlah http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is
Gambar 3-5. File HEAD menunjuk ke cabang tempat Anda berada.
HEAD
dimaksud tergantung pada apakah Anda berbicara tentang repo telanjang dan non-telanjang. Dalam konteks repo non-telanjang, ini secara efektif mengacu pada komit yang sedang diperiksa, yang tidak mengharuskan ada cabang yang melekat padanya (yaitu ketika dalam HEAD
keadaan terpisah ).
Sebuah cabang sebenarnya adalah pointer yang memegang komit ID seperti 17a5 . HEAD adalah pointer ke cabang yang sedang dikerjakan pengguna.
HEAD memiliki filw referensi yang terlihat seperti ini:
ref:
Anda dapat memeriksa file-file ini dengan mengakses .git/HEAD
.git/refs
yang ada di dalam repositori tempat Anda bekerja.
Git
adalah semua tentang komitmen.
Dan Head
menunjuk komit yang saat ini Anda periksa.
$ git cat-file -t HEAD
commit
Setiap kali Anda checkout cabang, HEAD menunjuk komit terbaru di cabang itu. Isi KEPALA dapat diperiksa seperti di bawah ini (untuk cabang utama):
$ cat .git/refs/heads/master
b089141cc8a7d89d606b2f7c15bfdc48640a8e25
Sebagai sebuah konsep, kepala adalah revisi terbaru di cabang. Jika Anda memiliki lebih dari satu kepala per cabang bernama Anda mungkin membuatnya ketika melakukan komit lokal tanpa penggabungan, secara efektif membuat cabang yang tidak disebutkan namanya.
Untuk memiliki repositori "bersih", Anda harus memiliki satu kepala per cabang bernama dan selalu bergabung ke cabang bernama setelah Anda bekerja secara lokal.
Ini juga berlaku untuk Mercurial .