Apa yang terjadi pada git commit yang dibuat dalam status HEAD terlepas?

142

Inilah yang terjadi:

Saya memiliki cabang A. Pada cabang AI melakukan banyak perubahan. Saya tidak puas dengan kodenya, jadi saya memeriksa komit sebelumnya di cabang A. Saya kemudian membuat lebih banyak perubahan dan berkomitmen pada cabang A. Sekarang saya tidak dapat menemukan komit ini di mana pun. Apakah saya kehilangan kode ini?

Mausimo
sumber
Saat Anda mengatakan "Saya memeriksa komit sebelumnya di cabang A", apakah maksud Anda "Saya menyetel ulang cabang A ke komit sebelumnya"? yaitu apakah Anda sebenarnya git resetlebih suka git checkout?
CB Bailey
Tidak, saya menggunakan pembayaran. reflog bekerja.
Mausimo
Jika Anda menggunakan checkout maka Anda akan berada di detached HEADdan cabang A akan tetap di commit sebelumnya. Tepatnya perintah apa yang Anda jalankan?
CB Bailey
1
Saya menggunakan GUI SourceTree GIT di OSX Lion. Saya berada di cabang A dan menjalankan pembayaran dari komit sebelumnya di Cabang A. Saya kemudian melakukan banyak perubahan kode dan berkomitmen (Cabang A). Saya yakin saya memiliki HEAD yang terpisah.
Mausimo
OK, saya pikir saya bingung ketika Anda mengatakan bahwa Anda berkomitmen perubahan banyak lebih pada cabang A .
CB Bailey

Jawaban:

194

Komitmen lama masih dalam reflog.

git reflog

Ini akan menampilkan daftar komit, dan komit yang "hilang" seharusnya ada di sana. Anda bisa membuatnya menjadi cabang baru. Misalnya, jika SHA-1 adalah ba5a739, Anda dapat membuat cabang baru bernama "new-branch" di komit lama dengan:

git branch new-branch ba5a739

Perhatikan bahwa komit yang "hilang" akan terhapus saat database dipangkas.

Dietrich Epp
sumber
16
Gunakan git cherry-pick [SHA]untuk memindahkan komit ke cabang yang ada jika Anda tidak sengaja berkomitmen saat berada dalam status kepala terpisah
Jan Aagaard Meier
3
Atau Anda dapat beralih ke cabang yang ada dan melakukan "git merge HEAD @ {n}" n sesuai dengan commit "hilang" yang tercantum dalam reflog.
eaykin
Apakah Anda tahu jika prunekomit akan menghapus juga terlepas yang sedang direferensikan dalam pesan komit? Atau itu membuat mereka bisa dihubungi ?
Kamafeather
@Kamae: Saya rasa itu tidak membuat mereka bisa dijangkau.
Dietrich Epp
Saya pikir begitu. Meh ... itu akan menjadi fitur yang bagus untuk mereferensikan pohon yang ditulis ulang / hilang (untuk permintaan tarik yang ditinjau, dalam kasus saya) [Mungkin saya harus membuka permintaan fitur!]. Terima kasih.
Kamafeather
66

Komit Anda masih tersedia di reflog, seperti yang sudah ditunjukkan. Selain jawaban lainnya, berikut adalah cara untuk mengambil alih komit HEAD yang terlepas ke cabang Anda saat ini secara langsung , tanpa membuat dan menggabungkan cabang baru:

  1. Cari hash SHA-1 dari komit yang Anda buat dalam status HEAD terpisah

    git reflog
    
  2. Kemudian jalankan, dengan semua hash komit yang diurutkan dari yang terlama ke terbaru:

    git cherry-pick <hash1> <hash2> <hash3> ...
    

    Misalnya jika saya hanya punya satu, diberikan dalam format hash pendek "7 karakter pertama":

    git cherry-pick a21d053
    

Ini akan membuat komit baru ke cabang Anda saat ini, satu komit per hash komit terpisah-HEAD yang Anda sebutkan di perintah. Itu juga mengambil alih pesan komit asli.

tanius
sumber
12

Anda mungkin menemukan komitmen yang hilang (menggantung) dengan perintah berikut:

git fsck --lost-found

Perhatikan, jika kepala Anda saat ini menggantung komit, itu tidak terdaftar sebagai hilang.

Anda dapat menemukan info lebih lanjut di git-fsck (1) Halaman Manual

Kemudian Anda dapat membuat cabang pada komit yang hilang itu:

git branch new-branch ba5a739
sergtk
sumber
Saya pertama kali menggunakan perintah "git reflog" lalu "git branch new-branch ba5a739" untuk submodule, itu berhasil.
ondermerol
7

Bahasa Git untuk status direktori kerja Anda adalah " HEAD terpisah ". Inilah tempat lain yang git reflogmelakukan penyelamatan.

$ git reflog
0b40dd6 HEAD@{0}: commit: my commit on detached HEAD
...

Jika saya mencoba untuk memeriksa cabang yang berbeda, git-1.7.5.1 memberikan saran yang berguna.

Master checkout $ git
Peringatan: Anda meninggalkan 1 komit, tidak terhubung ke
salah satu cabang Anda:

  0b40dd6 komit saya pada HEAD terpisah

Jika Anda ingin menyimpannya dengan membuat cabang baru, ini mungkin saat yang tepat
untuk melakukannya dengan:

 git branch new_branch_name 0b40dd65c06bb215327863c2ca10fdb4f904215b

Beralih ke 'master' cabang
Greg Bacon
sumber
6

Anda tidak kehilangannya, Git masih menyimpan salinannya (tetapi saat ini tidak dapat dijangkau oleh kepala cabang mana pun). Anda dapat menemukan komit Anda yang hilang menggunakan git reflogperintah. Reflog melacak posisi historis dari kepala cabang, dan Anda dapat menggunakannya untuk menemukan hal-hal yang ditunjuk oleh kepala cabang sebelumnya.

Greg Hewgill
sumber
4

Ikuti langkah-langkah ini untuk menautkan kepala Anda yang terpisah kembali ke git repo

  1. git checkout "your branch with path but without remote name"

Misalnya jika nama remote adalah origin dan nama cabang bugfix/somebranchkemudian digunakangit checkout bugfix/somebranch

  1. git reflog dapatkan komit SHA yang terdaftar dari daftar komit Anda dari cabang yang terpisah.

  2. git cherry-pick "commit hash1" "commit hash2" "commit hash3"

  3. git push

SIAP!!

pengguna1520615
sumber
2

Di Sourcetree, saya menemukan bahwa git reflog tidak berfungsi, jadi saya menemukan cara melakukannya menggunakan GUI.

Pertama, coba temukan komit "hilang" dengan mencari pesan di Riwayat Perintah (tampilan: Tampilkan Output Perintah). Mudah-mudahan akan ada di perintah "Switching Branch" setelah komit yang hilang dan Anda akan melihat komentar komit dengan ID komit 1234567.

Bawa ID Komit itu ke langkah berikutnya.

Tekan tombol "Cabang" di toolbar bagian atas dan Anda akan mendapatkan dialog "Cabang Baru" di mana Anda dapat menentukan komit tertentu. Letakkan ID Komit di sana, tentukan nama cabang baru, tekan Buat Cabang dan Anda akan mendapatkan cabang baru dengan komit yang hilang!

Ini membawa kembali beberapa pekerjaan yang hilang untuk saya!

pirang
sumber