Pertanyaan Bagaimana cara mendamaikan KEPALA yang terpisah dengan master / asal?


Saya baru di kompleks percabangan Git. Saya selalu bekerja pada satu cabang dan melakukan perubahan dan kemudian secara berkala mendorong ke asal saya yang terpencil.

Di suatu tempat baru-baru ini, saya melakukan reset beberapa file untuk mengeluarkan mereka dari pementasan, dan kemudian melakukan rebase -i untuk menyingkirkan beberapa komit lokal baru-baru ini. Sekarang saya dalam keadaan yang saya tidak mengerti.

Di wilayah kerja saya, git log menunjukkan apa yang saya harapkan - Saya di kereta kanan dengan komit yang tidak saya inginkan, dan yang baru di sana, dll.

Tapi saya hanya mendorong ke repositori jarak jauh, dan apa yang ada berbeda - beberapa komit yang saya bunuh dalam rebase terdorong, dan yang baru dilakukan secara lokal tidak ada.

Saya pikir "master / origin" terpisah dari HEAD, tetapi saya tidak 100% jelas apa artinya, bagaimana memvisualisasikannya dengan alat baris perintah, dan bagaimana memperbaikinya.


1274
2018-04-24 17:51


asal


Jawaban:


Pertama, mari kita perjelas apa KEPALA dan apa artinya ketika itu terlepas.

HEAD adalah nama simbol untuk komit yang diperiksa saat ini. Ketika KEPALA tidak terlepas ("normal"1 Situasi: Anda memiliki cabang yang dicentang), HEAD sebenarnya menunjuk ke "ref" cabang dan cabang menunjuk ke komit. KEPALA demikian "melekat" ke cabang. Saat Anda membuat commit baru, cabang yang HEAD arahkan ke diperbarui untuk menunjuk ke commit baru. HEAD mengikuti secara otomatis karena hanya menunjuk ke cabang.

  • git symbolic-ref HEAD hasil refs/heads/master
    Cabang bernama "tuan" diperiksa.
  • git rev-parse refs/heads/master menghasilkan 17a02998078923f2d62811326d130de991d1a95a
    Komit itu adalah tip saat ini atau "kepala" dari cabang master.
  • git rev-parse HEAD juga menghasilkan 17a02998078923f2d62811326d130de991d1a95a
    Ini adalah apa artinya menjadi "ref simbolis". Ini menunjuk ke suatu objek melalui beberapa referensi lain.
    (Symbolic refs awalnya diimplementasikan sebagai tautan simbolis, tetapi kemudian diubah menjadi file biasa dengan interpretasi ekstra sehingga mereka dapat digunakan pada platform yang tidak memiliki symlink.)

Kita punya HEAD → refs/heads/master → 17a02998078923f2d62811326d130de991d1a95a

Ketika HEAD terlepas, ia menunjuk langsung ke komit — alih-alih secara tidak langsung menunjuk ke satu melalui cabang. Anda dapat menganggap KEPALA yang terpisah berada di cabang yang tidak disebutkan namanya.

  • git symbolic-ref HEAD gagal dengan fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEAD hasil 17a02998078923f2d62811326d130de991d1a95a
    Karena ini bukan ref simbolik, ia harus menunjuk langsung ke komitmen itu sendiri.

Kita punya HEAD → 17a02998078923f2d62811326d130de991d1a95a

Hal yang penting untuk diingat dengan HEAD yang terpisah adalah bahwa jika komit yang dituju sebaliknya tidak direferensikan (tidak ada referensi lain yang dapat mencapainya), maka itu akan menjadi "menggantung" ketika Anda memeriksa beberapa commit lainnya. Akhirnya, komitmen yang menggantung tersebut akan dipangkas melalui proses pengumpulan sampah (secara default, mereka disimpan selama setidaknya 2 minggu dan dapat disimpan lebih lama dengan direferensikan oleh reflog HEAD).

1 Sangatlah baik untuk melakukan pekerjaan "normal" dengan KEPALA yang terpisah, Anda hanya perlu melacak apa yang Anda lakukan untuk menghindari hilangnya riwayat ikan dari reflog.


Langkah-langkah perantara rebase interaktif dilakukan dengan KEPALA yang terpisah (sebagian untuk menghindari polusi reflektor cabang aktif). Jika Anda menyelesaikan operasi rebase penuh, itu akan memperbarui cabang asli Anda dengan hasil kumulatif operasi rebase dan memasang kembali KEPALA ke cabang asli. Tebakan saya adalah bahwa Anda tidak pernah sepenuhnya menyelesaikan proses rebase; ini akan meninggalkan Anda dengan KEPALA terpisah yang menunjuk ke komit yang baru-baru ini diproses oleh operasi rebase.

Untuk memulihkan dari situasi Anda, Anda harus membuat cabang yang menunjuk ke komit yang saat ini ditunjukkan oleh KEPALA Anda yang terpisah:

git branch temp
git checkout temp

(dua perintah ini bisa disingkat menjadi git checkout -b temp)

Ini akan menyambungkan KEPALA Anda ke yang baru temp cabang.

Selanjutnya, Anda harus membandingkan commit saat ini (dan sejarahnya) dengan cabang normal yang Anda harapkan dapat berfungsi:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Anda mungkin ingin bereksperimen dengan opsi log: tambahkan -p, tinggalkan --pretty=… untuk melihat seluruh pesan log, dll.)

Jika baru Anda temp cabang terlihat bagus, Anda mungkin ingin memperbarui (mis.) master untuk menunjukkannya:

git branch -f master temp
git checkout master

(dua perintah ini bisa disingkat menjadi git checkout -B master temp)

Anda kemudian dapat menghapus cabang sementara:

git branch -d temp

Akhirnya, Anda mungkin ingin mendorong sejarah yang telah ditetapkan kembali:

git push origin master

Anda mungkin perlu menambahkan --force hingga akhir dari perintah ini untuk mendorong jika cabang jarak jauh tidak dapat "diteruskan dengan cepat" ke commit baru (yaitu Anda menjatuhkan, atau menulis ulang beberapa commit yang ada, atau menulis ulang sedikit sejarah).

Jika Anda berada di tengah-tengah operasi rebase, Anda mungkin harus membersihkannya. Anda dapat memeriksa apakah rebase sedang diproses dengan mencari direktori .git/rebase-merge/. Anda dapat membersihkan rebase yang sedang diproses secara manual hanya dengan menghapus direktori tersebut (mis. Jika Anda tidak lagi mengingat tujuan dan konteks operasi rebase aktif). Biasanya Anda akan menggunakannya git rebase --abort, tetapi itu melakukan beberapa pengaturan ulang tambahan yang mungkin ingin Anda hindari (ia memindahkan KEPALA kembali ke cabang asli dan menyetel ulang kembali ke commit asli, yang akan membatalkan sebagian dari pekerjaan yang kita lakukan di atas).


2160
2018-04-24 19:56



Lakukan saja ini:

git checkout master

Atau, jika Anda memiliki perubahan yang ingin Anda simpan, lakukan ini:

git checkout -b temp
git checkout -B master temp

512
2017-09-18 07:23



Saya mengalami masalah ini dan ketika saya membaca di bagian atas memilih jawaban:

HEAD adalah nama simbol untuk komit yang diperiksa saat ini.

Saya pikir: Ah-ha! Jika HEAD adalah nama simbol untuk checkout checkout currenlty, saya dapat mendamaikannya master dengan mengubahnya kembali master:

git rebase HEAD master

Perintah ini:

  1. check out master
  2. mengidentifikasi komitmen orang tua dari HEAD kembali ke intinya HEAD menyimpang dari master
  3. memainkan mereka melakukan di atas master

Hasil akhirnya adalah semua komit yang ada HEAD tapi tidak master kemudian juga masuk master. master tetap diperiksa.


Mengenai remote:

beberapa komit yang kubunuh dalam rebase itu didorong, dan yang baru dilakukan secara lokal tidak ada di sana.

Riwayat jarak jauh tidak dapat lagi diteruskan dengan cepat menggunakan riwayat lokal Anda. Anda harus mendorong-paksa (git push -f) untuk menimpa riwayat jarak jauh. Jika Anda memiliki kolaborator, biasanya masuk akal untuk mengoordinasikan ini dengan mereka sehingga semua orang ada di halaman yang sama.

Setelah kamu mendorong master ke remote origin, cabang pelacakan jarak jauh Anda origin/master akan diperbarui untuk mengarah ke komit yang sama dengan master.


97
2017-08-02 03:10



Lihat di sini untuk penjelasan dasar kepala terpisah:

http://git-scm.com/docs/git-checkout

Command line untuk memvisualisasikannya:

git branch

atau

git branch -a

Anda akan mendapatkan output seperti di bawah ini:

* (no branch)
master
branch1

Itu * (no branch) menunjukkan Anda berada di kepala terpisah.

Anda bisa datang ke negara ini dengan melakukan git checkout somecommit dll. dan itu akan memperingatkan Anda dengan yang berikut:

Anda berada di negara 'terpisah HEAD'. Kamu   dapat melihat-lihat, membuat eksperimental   berubah dan lakukan, dan Anda bisa   buang semua komitmen yang Anda lakukan dalam hal ini   negara tanpa mempengaruhi cabang apa pun   dengan melakukan checkout lain.

Jika Anda ingin membuat cabang baru ke   pertahankan komitmen yang Anda buat, Anda dapat melakukannya   jadi (sekarang atau nanti) dengan menggunakan -b dengan   perintah checkout lagi. Contoh:

git checkout -b new_branch_name

Sekarang, untuk membawa mereka ke master:

Lakukan a git reflog atau bahkan adil git log dan perhatikan komitmen Anda. Sekarang git checkout master dan git merge komit.

git merge HEAD@{1}

Edit:

Untuk menambah, gunakan git rebase -i tidak hanya untuk menghapus / membunuh commit yang tidak Anda butuhkan, tetapi juga untuk mengeditnya. Cukup sebutkan "edit" dalam daftar komit dan Anda akan dapat mengubah komitmen Anda dan kemudian menerbitkan git rebase --continue untuk terus maju. Ini akan memastikan bahwa Anda tidak pernah masuk ke KEPALA yang terpisah.


78
2018-04-24 18:41



Dapatkan komitmen Anda terpisah ke cabang sendiri

Cukup jalankan git checkout -b mynewbranch.

Lalu lari git log, dan Anda akan melihat komitmen itu sekarang HEAD di cabang baru ini.


29
2018-05-20 02:44



jika Anda baru saja menguasai cabang dan ingin kembali ke "mengembangkan" atau fitur hanya melakukan ini:

git checkout origin/develop

Catatan: memeriksa asal / berkembang.

Anda masuk KEPALA yang terpisah negara. Anda dapat melihat-lihat, membuat eksperimental ubah dan komit mereka, dan Anda dapat membuang komitmen apa pun yang Anda buat dalam hal ini negara tanpa mempengaruhi cabang apa pun dengan melakukan checkout lain ...

kemudian

git checkout -b develop

Berhasil :)


18
2017-11-08 13:24



Jika Anda ingin menekan HEAD Anda saat ini (periksa git log sebelumnya), coba:

git push origin HEAD:master

untuk mengirim KEPALA Anda yang terpisah ke dalam cabang induk pada titik asal. Jika dorongan Anda ditolak, cobalah git pull origin master pertama untuk mendapatkan perubahan dari asal. Jika Anda tidak peduli tentang perubahan dari asal dan itu ditolak, karena Anda melakukan rebase disengaja dan Anda ingin mengganti asal / master dengan cabang Anda saat ini terpisah - maka Anda dapat memaksanya (-f). Jika Anda kehilangan beberapa akses ke commit sebelumnya, Anda selalu dapat menjalankannya git reflog untuk melihat sejarah dari semua cabang.


Untuk kembali ke cabang utama, sambil menyimpan perubahan, coba perintah berikut:

git rebase HEAD master
git checkout master

Lihat: Git: "Tidak saat ini di cabang mana pun." Adakah cara mudah untuk kembali ke cabang, sambil mempertahankan perubahan?


16
2017-09-17 20:35



Jika Anda benar-benar yakin KEPALA adalah keadaan baik:

git branch -f master HEAD
git checkout master

Anda mungkin tidak dapat mendorong ke asal, karena tuan Anda telah menyimpang dari asalnya. Jika Anda yakin tidak ada orang lain yang menggunakan repo, Anda dapat menekan paksa:

git push -f

Paling berguna jika Anda berada di cabang fitur yang tidak digunakan orang lain.


7
2018-03-01 09:31