Bagaimana cara mengedit pesan komit yang salah di git (yang saya dorong)?

152

Saya ingin mengubah pesan komit lebih dalam dalam sejarah dan saya telah mendorong banyak komitmen baru.

Bagaimana cara mengubah pesan komit? Apa itu mungkin?

Mehdi Raash
sumber

Jawaban:

125

Pesan dari Linus Torvalds dapat menjawab pertanyaan Anda:

Ubah / edit pesan komit lama

Jawaban singkat: Anda tidak bisa (jika didorong).


ekstrak (Linus merujuk pada BitKeeper sebagai BK):

Catatan tambahan, hanya karena minat historis: di BK Anda bisa.

Dan jika Anda terbiasa (seperti saya) itu benar-benar sangat praktis. Saya akan menerapkan patch-bom dari Andrew, melihat ada sesuatu yang salah, dan hanya mengeditnya sebelum mendorongnya keluar.

Saya bisa melakukan hal yang sama dengan git. Itu akan cukup mudah untuk membuat pesan komit tidak menjadi bagian dari nama, dan masih menjamin bahwa sejarah tidak tersentuh, dan memungkinkan hal "perbaiki komentar nanti".

Tetapi saya tidak melakukannya.

Sebagian darinya murni "konsistensi internal". Git hanyalah sebuah sistem pembersih berkat semua yang dilindungi SHA1, dan semua objek diperlakukan sama, apa pun jenis objeknya. Ya, ada empat jenis objek, dan semuanya sangat berbeda, dan mereka tidak dapat digunakan dengan cara yang sama, tetapi pada saat yang sama, bahkan jika penyandiannya mungkin berbeda pada disk, secara konsep mereka semua bekerja persis sama.

Tetapi konsistensi internal sebenarnya bukan alasan untuk tidak fleksibel, dan jelas itu akan sangat fleksibel jika kita bisa memperbaiki kesalahan setelah itu terjadi. Jadi itu bukan argumen yang sangat kuat.

The nyata Alasan git tidak memungkinkan Anda untuk mengubah pesan komit ujung menjadi sangat sederhana: bahwa cara, Anda dapat mempercayai pesan. Jika Anda mengizinkan orang untuk mengubahnya setelah itu, pesan-pesannya secara inheren tidak terlalu dapat dipercaya.


Agar lengkap, Anda dapat menulis ulang riwayat komit lokal Anda untuk mencerminkan apa yang Anda inginkan, seperti yang disarankan oleh sykora (dengan beberapa rebase dan reset --hard, terkesiap!)

Namun, begitu Anda menerbitkan riwayat revisi Anda lagi (dengan git push origin +master:master, +tanda yang memaksa terjadi, bahkan jika itu tidak menghasilkan komit "maju cepat") ... Anda mungkin akan mendapat masalah .

Ekstrak dari pertanyaan SO lainnya ini:

Saya sebenarnya pernah didorong dengan repositori --force ke git.git dan dimarahi oleh Linus BIG TIME. Ini akan menciptakan banyak masalah bagi orang lain. Jawaban sederhana adalah "jangan lakukan itu".

VONC
sumber
jawaban yang bagus. Apakah Anda tahu jika sekarang Anda dapat mengubah pesan komit yang sudah didorong dalam versi git yang lebih baru? Apakah ada yang berubah sejak ini diposting di '09?
David West
@ DavidvidWest memegang prinsip yang sama: Anda dapat menulis ulang sejarah Anda dan memaksakan dorongan.
VonC
2
Untuk membuat hal-hal lebih spesifik, jika Anda mengubah / rebase melakukan, pengidentifikasi komitnya (hash heksadesimal dalam indeks git) pasti akan berubah; itu berarti komit yang diedit diperlakukan berbeda dari komit lama dalam sejarah git VCS. Dikatakan, jika anggota tim dev Anda sayangnya sudah menarik komitmen lama, mereka berkewajiban untuk menarik komitmen yang sudah diedit, baru, dan melakukan penggabungan antara yang lama dan yang baru di copy pekerjaan lokal mereka.
Shigerello
1
Lebih baik untuk mendorong komit yang diedit kembali demi kenyamanan bagi kolega Anda, sehingga dengan baik menghapuskan kebutuhan penggabungan dalam copy pekerjaan kolega.
Shigerello
28

Saat ini git ganti mungkin melakukan trik.

Secara detail: Buat cabang kerja sementara

git checkout -b temp

Setel ulang ke komit untuk menggantikan

git reset --hard <sha1>

Ubah komit dengan pesan yang benar

git commit --amend -m "<right message>"

Ganti komit lama dengan yang baru

git replace <old commit sha1> <new commit sha1>

kembali ke cabang di mana kamu berada

git checkout <branch>

menghapus cabang temp

git branch -D temp

Dorong

guess

selesai

Johan
sumber
11
@Jonah: Saya mendapat pesan "Semuanya mutakhir" ketika saya mencoba untuk mendorong ke cabang jauh
Simon Kagwi
1
Seperti disebutkan dalam jawaban lain: gunakan rebase -i dengan reword. Dan itu akan menulis ulang sejarah.
Sylvain
Terima kasih atas solusinya, yang saya cari. Anda menghemat waktu saya!
Tomasz Kuter
1
@ Jon - Saya punya masalah ... solusi Anda memperbarui log komit saya secara lokal, tetapi tidak jauh. Bagaimana cara mendorong mereka ke sana?
Tomasz Kuter
1
@ ThomaszKuter, saya punya masalah yang sama seperti Anda. Pesan komit saya tidak diperbarui dari jarak jauh. Saya menyelesaikannya dengan menggunakan bantuan berikut dari GitHub: help.github.com/articles/changing-a-commit-message . Ikuti: Mengubah bagian pesan komit yang lebih lama atau lebih dari satu. Ini pada dasarnya adalah jawaban dari bawah yang diberikan oleh user987419 Jika Anda sudah mengubah pesan komit, Anda dapat memilih dan menyimpannya tanpa harus mengubahnya lagi.
evaldeslacasa
19

Kamu bisa memakai git rebase -i (melawan cabang tempat Anda bercabang) 'i' untuk interaktif.

Ganti pickkomentar komit yang ingin Anda ubah dengan r(ataureword ), simpan dan keluar dan setelah melakukannya Anda akan dapat mengedit.

git push sekali lagi dan kamu selesai!

Marcus
sumber
1
Ini tidak memungkinkan seseorang untuk mengedit pesan pada gabungan komitmen. Apakah itu mungkin dengan beberapa varian dari perintah ini?
Andrew Mao
1
Coba -pargumen penggabungan cadangan rebasemana p.
Cactus
3
Saya suka prosedur ini, tetapi awalnya tidak begitu mengerti jawabannya. Jika seseorang membutuhkan bantuan, halaman Bantuan Githulb menawarkan informasi yang baik tentang hal itu: help.github.com/articles/changing-a-commit-message
evaldeslacasa
15

Misalkan Anda memiliki pohon seperti ini:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]

Pertama, checkoutcabang temp:

git checkout -b temp

Di tempcabang, reset --hardke komit yang ingin Anda ubah pesannya (misalnya, komit itu adalah 946992):

git reset --hard 946992

Gunakan amenduntuk mengubah pesan:

git commit --amend -m "<new_message>"

Setelah itu pohon akan terlihat seperti ini:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            b886a0 [temp]

Lalu, cherry-picksemua komit yang ada di depan 946992dari masterke tempdan komit mereka, gunakan amendjika Anda ingin mengubah pesan mereka juga:

git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>

Pohon itu sekarang terlihat seperti ini:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
               \
                b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]

Sekarang paksa dorong temp temp branch ke jarak jauh:

git push --force origin temp:master

Langkah terakhir, hapus cabang masterdi lokal, git fetch originuntuk menarik cabang masterdari server, lalu beralih ke cabang masterdan hapus cabang temp.

Sekarang baik lokal maupun jarak jauh Anda akan memperbarui semua pesan.

Huy Vo
sumber
5

Di toko kami, saya memperkenalkan konvensi penambahan tag beranotasi yang dapat dikenali untuk melakukan pesan yang salah, dan menggunakan anotasi sebagai penggantinya.

Meskipun ini tidak membantu orang-orang yang menjalankan perintah "git log" biasa, itu memberi kami cara untuk memperbaiki referensi pelacak bug yang salah dalam komentar, dan semua alat membangun dan melepaskan saya memahami konvensi.

Ini jelas bukan jawaban umum, tetapi mungkin sesuatu yang dapat diadopsi orang dalam komunitas tertentu. Saya yakin jika ini digunakan dalam skala yang lebih besar, semacam dukungan porselen untuk itu mungkin muncul, akhirnya ...

Christian Goetze
sumber
3
"git notes" mungkin memiliki tujuan yang sama
Christian Goetze
2

(Dari http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0 )

Bagaimana mengubah komitmen lebih dalam dalam sejarah

Karena sejarah di Git tidak dapat diubah, memperbaiki apa pun kecuali komit terbaru (komit yang bukan kepala cabang) mensyaratkan bahwa sejarah ditulis ulang dari komit yang diubah dan maju.

Anda dapat menggunakan StGIT untuk itu, menginisialisasi cabang jika perlu, tidak berkomitmen hingga komit yang ingin Anda ubah, pop ke sana jika perlu, buat perubahan lalu segarkan tambalan (dengan opsi -e jika Anda ingin memperbaiki pesan komit), lalu tekan semuanya dan stg berkomitmen.

Atau Anda dapat menggunakan rebase untuk melakukan itu. Buat cabang sementara baru, mundurkan ke komit yang ingin Anda ubah menggunakan git reset --hard, ubah komit (itu akan menjadi di atas kepala saat ini), kemudian rebase cabang di atas komit yang diubah, menggunakan git rebase --onto.

Atau Anda dapat menggunakan git rebase --interactive, yang memungkinkan berbagai modifikasi seperti pemesanan ulang tambalan, ...

Saya pikir itu harus menjawab pertanyaan Anda. Namun, perhatikan bahwa jika Anda telah mendorong kode ke repositori jarak jauh dan orang-orang telah menariknya, maka ini akan mengacaukan sejarah kode mereka, serta pekerjaan yang telah mereka lakukan. Jadi lakukan dengan hati-hati.

sykora
sumber
Jawaban yang baik dalam teori, sangat berbahaya dalam praktik: lihat stackoverflow.com/questions/253055#432518
VonC
0

Jika Anda menggunakan Git Extensions: masuk ke layar Commit, harus ada kotak centang yang mengatakan "Amend Commit" di bagian bawah, seperti yang dapat dilihat di bawah:

masukkan deskripsi gambar di sini

batsheva
sumber
@KrunalPandya ya, atau cukup tekan komit & push
batsheva