Mengapa repo Git saya memasuki kondisi HEAD yang terpisah?

387

Saya berakhir dengan kepala yang terpisah hari ini, masalah yang sama seperti yang dijelaskan dalam: git push mengatakan semuanya mutakhir meskipun saya memiliki perubahan lokal

Sejauh yang saya tahu saya tidak melakukan sesuatu yang luar biasa, hanya melakukan dan mendorong dari repo lokal saya.

Jadi bagaimana saya bisa mendapatkan detached HEAD?

Adam Bergmark
sumber
18
Memeriksa cabang jarak jauh sepertinya cara paling umum untuk melakukan hal ini secara tidak sengaja; cara umum lainnya adalah dengan check out branch-name@{n}, posisi ke - 9 sebelumnya branch-name. Tapi tidak peduli apa, pada titik tertentu pasti ada git checkout <rev>. Jika itu tidak membunyikan bel, maka mungkin Anda melakukan apa yang disebutkan Will - coba lakukan git checkout <file>dan berhasil menentukan revisi secara tidak sengaja.
Cascabel
3
Untuk membatalkan status HEAD yang terlepas, lihat Memperbaiki kepala yang terlepas Git? .
Repo saya berakhir di negara ini ketika konflik ditemukan selama rebasing. Untungnya Git mengatakan kepada saya apa yang harus dilakukan ketika saya berlari git status:all conflicts fixed: run "git rebase --continue"
Paul
2
Juga yang terjadi jika Anda secara tidak sengaja mengetik git checkout remotes/origin/my-branchbukan git checkout my-branchatau git checkout origin/my-branch.
Adam Libuša
@ Madam Libusa, Terima kasih itu berhasil untuk saya. Apa perbedaan antara remote checkout git / origin / my-branch dan git checkout my-branch. Bukankah itu tidak sama? tetapi apa yang Anda katakan bekerja untuk saya. Karena penasaran saya bertanya.
karunakar bhogyari

Jawaban:

281

Setiap checkout dari komit yang bukan nama salah satu cabang Anda akan membuat Anda HEAD terpisah. A SHA1 yang mewakili ujung cabang masih memberikan KEPALA terpisah. Hanya checkout dari nama cabang lokal yang menghindari mode itu.

Lihat melakukan dengan KEPALA terpisah

Ketika HEAD dilepaskan, komit berfungsi seperti biasa, kecuali tidak ada cabang bernama diperbarui. (Anda dapat menganggap ini sebagai cabang anonim.)

teks alternatif

Misalnya, jika Anda checkout "cabang jarak jauh" tanpa melacaknya terlebih dahulu, Anda dapat berakhir dengan KEPALA terpisah.

Lihat git: beralih cabang tanpa melepaskan kepala


Dengan Git 2.23 (Agustus 2019), Anda tidak perlu menggunakan perintah yang membingungkangit checkout lagi.

git switch juga dapat checkout cabang, dan mendapatkan KEPALA lepas, kecuali:

  • ia memiliki --detachopsi eksplisit

Untuk memeriksa komit HEAD~3untuk inspeksi atau eksperimen sementara tanpa membuat cabang baru:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • itu tidak dapat terlepas oleh cabang pelacakan jarak jauh

Lihat:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

Vs. menggunakan git switchperintah baru :

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

Jika Anda ingin membuat cabang lokal baru yang melacak cabang jarak jauh:

git switch <branch> 

Jika <branch>tidak ditemukan tetapi ada cabang pelacakan di persis satu remote (sebut saja <remote>) dengan nama yang cocok, perlakukan setara dengan

git switch -c <branch> --track <remote>/<branch>

Tidak salah lagi!
Tidak ada lagi KEPALA terlepas yang tidak diinginkan!

VONC
sumber
12
Cara lain Anda dapat memasukkan status kepala terpisah adalah jika Anda berada di tengah rebase interaktif, dan Anda ingin mengedit salah satu komit. Ketika Git menjatuhkan Anda di komit untuk mengedit, Anda akan berada dalam kondisi kepala yang terpisah sampai Anda menyelesaikan rebase.
Dalam panduan visual ini, ada penjelasan ini: git commit files creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.Apa yang dimaksud dengan "file disalin ke panggung"? Saya pikir file-file tersebut dikomit, yang berarti tahap dihapus?
maks.
16
Bahkan, Anda akan mendapatkan KEPALA terpisah setiap kali Anda melakukan checkout komitmen oleh SHA1-nya, apakah itu di ujung cabang; satu-satunya hal yang dapat Anda checkout tanpa KEPALA terlepas adalah nama cabang. Misalnya, meskipun masterberada ed489pada diagram di atas, git checkout ed489akan memberi Anda KEPALA terpisah, sementara git checkout mastertidak.
musiphil
8
"You can think of this as an anonymous branch":) Saya suka analoginya
Adrien Be
118

Saya mereproduksi ini barusan secara tidak sengaja:

  1. daftar cabang jarak jauh

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. Saya ingin checkout secara lokal, jadi saya memotong tempel:

    git checkout origin/Feature/f1234
    
  3. Presto! Keadaan HEAD terlepas

    You are in 'detached HEAD' state. [...])
    

Solusi # 1:

Jangan sertakan origin/di bagian depan spek cabang saya saat memeriksa:

git checkout Feature/f1234

Solusi # 2:

Tambahkan -bparameter yang membuat cabang lokal dari jarak jauh

git checkout -b origin/Feature/f1234 atau

git checkout -b Feature/f1234 itu akan kembali ke asal secara otomatis

Owen
sumber
14
Ini hampir merupakan jawaban yang bagus, tetapi gagal menjelaskan mengapa Anda menjadi kepala negara yang terpisah.
Angsa
5
Saya setuju tetapi tidak memberikan solusi yang saya cari. Terima kasih!!
Kilmazing
Saya melihat dalam jawaban lain ini bahwa git checkout -b Feature/f1234<=> git branch Feature/f1234dan git checkout Feature/f1234.
Armfoot
1
secara default itu terlihat asli, jadi ketika Anda memberi origin/branchname, ia mencari origin/origin/branchnametahu bahwa yang pertama adalah nama jarak jauh yang Anda gunakan -b, jika Anda tidak membuatnya membuat anonymouscabang yang terlepas. Demikian pula untuk memeriksa dari remote yang berbeda Anda harus menyebutkan -bparameter jika git tidak memiliki cara untuk mengetahui itu dari remote baru, ia akan mencari origin/remote/branchname.
garg10mungkin
Anda seorang suci!
Harvey Lin
12

mencoba

git reflog 

ini memberi Anda sejarah tentang bagaimana KEPALA dan pointer cabang Anda bergerak di masa lalu.

misalnya:

88ea06b HEAD @ {0}: checkout: pindah dari DEVELOPMENT ke remote / origin / SomeNiceFeature e47bf80 HEAD @ {1}: pull origin DEVELOPMENT: Maju cepat

bagian atas daftar ini adalah satu reasone yang mungkin ditemui kondisi HEAD DETACHED ... memeriksa cabang pelacakan jarak jauh.

André R.
sumber
7

Ini dapat dengan mudah terjadi jika Anda mencoba untuk membatalkan perubahan yang telah Anda lakukan dengan memeriksa kembali file dan tidak mendapatkan sintaks yang tepat.

Anda dapat melihat output dari git log- Anda dapat menempelkan ekor log di sini sejak komit terakhir yang berhasil, dan kita semua bisa melihat apa yang Anda lakukan. Atau Anda bisa menempel-bin itu dan bertanya dengan baik di #gitfreenode IRC.

Akan
sumber
5

Itu bisa terjadi jika Anda memiliki tag yang bernama sama dengan cabang.

Contoh: jika "release / 0.1" adalah nama tag, maka

git checkout release/0.1

menghasilkan HEAD terlepas pada "release / 0.1". Jika Anda mengharapkan rilis / 0,1 menjadi nama cabang, maka Anda bingung.

radzimir
sumber
1
Iya. Tetapi bagaimana Anda memperbaikinya? Bagaimana cara Anda keluar dari cabang?
Martin
5

Detached HEAD berarti apa yang saat ini diperiksa bukan cabang lokal.

Beberapa skenario yang akan menghasilkan Detached HEADkeadaan:

  • Jika Anda checkout cabang jauh , katakan origin/master. Ini adalah cabang read-only. Jadi, ketika membuat komit dari origin/masteritu akan mengambang bebas , yaitu tidak terhubung ke cabang apa pun.

  • Jika Anda checkout tag tertentu atau komit . Ketika melakukan komit baru dari sini, itu akan kembali mengambang bebas , yaitu tidak terhubung ke cabang apa pun. Perhatikan bahwa ketika cabang dicentang, komit baru selalu ditempatkan secara otomatis di ujung.

    Saat Anda ingin kembali dan checkout komit atau tag tertentu untuk mulai bekerja dari sana, Anda bisa membuat cabang baru yang berasal dari komit itu dan beralih dengan git checkout -b new_branch_name. Ini akan mencegah Detached HEADnegara karena Anda sekarang memiliki cabang diperiksa dan bukan komit.

Tim Skov Jacobsen
sumber
3

Cara sederhana yang tidak disengaja adalah dengan melakukan git checkout headsebagai salah ketik HEAD.

Coba ini:

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

pemberian yang mana

Note: checking out 'head'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9354043... Readme
Thomas Weller
sumber
Juga disebutkan di longair.net/blog/2012/05/07/the-most-confusing-git-terminology (cari "HEAD" dan "head" ")
VonC
@VonC: terima kasih atas tautannya. Saya sedang mempersiapkan pelatihan Git dan saya juga ingin menunjukkan mengapa kadang-kadang membingungkan. Saya sudah memiliki banyak contoh (seperti checkout -byang terlihat seperti checkout tetapi sebenarnya cabang) tetapi daftar lain hanya disambut.
Thomas Weller
2

Cara lain untuk masuk dalam kondisi head terpisah git adalah mencoba untuk berkomitmen ke cabang terpencil. Sesuatu seperti:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

Perhatikan bahwa jika Anda melakukan ini, upaya lebih lanjut untuk checkout asal / foo akan menjatuhkan Anda kembali ke keadaan kepala terpisah!

Solusinya adalah membuat cabang foo lokal Anda sendiri yang melacak asal / foo, lalu secara opsional dorong.

Ini mungkin tidak ada hubungannya dengan masalah awal Anda, tetapi halaman ini tinggi di google hits untuk "git detached head" dan skenario ini sangat tidak terdokumentasi.

dspeyer
sumber
Situasi ini tampaknya menjadi jawaban Owen di atas tentang - di mana memotong dan menempelkan "asal / foo" membuat git menganggapnya sebagai "asal / asal / foo".
mvanle
1

Saat Anda checkout ke komit git checkout <commit-hash>atau ke cabang jarak jauh, KEPALA Anda akan terlepas dan mencoba membuat komit baru di atasnya.

Komit yang tidak dapat dijangkau oleh cabang atau tag apa pun akan menjadi sampah yang dikumpulkan dan dihapus dari repositori setelah 30 hari.

Cara lain untuk mengatasi ini adalah dengan membuat cabang baru untuk komit yang baru dibuat dan memeriksa untuk itu. git checkout -b <branch-name> <commit-hash>

Artikel ini mengilustrasikan bagaimana Anda bisa mendapatkan status HEAD terpisah .

Nesha Zoric
sumber